创建函数是否会消耗更多内存

Ray*_*nos 7 javascript v8 spidermonkey

// Case A
function Constructor() {
  this.foo = function() {
    ...
  };
  ...
}

// vs 
// Case B
function Constructor() {
  ...
};

Constructor.prototype.foo = function() {
  ...
}
Run Code Online (Sandbox Code Playgroud)

人们建议使用原型的主要原因之一.foo是在原型的情况下创建一次,this.foo在使用其他方法时多次创建.

然而,人们会期望口译员能够优化这一点.因此foo在案例A中只有一个函数副本.

当然,由于闭包,每个对象仍然有一个唯一的范围上下文,但是每个对象的新函数开销较小.

现代JS解释器是否优化了案例A,因此只有一个函数副本foo?

bro*_*ofa 8

是的,创建函数会占用更多内存.

...而且,不,解释器不会将案例A优化为单一功能.

原因是JS作用域链要求函数的每个实例捕获它在创建时可用的变量.这就是说,现代的解释是更好地了解情况比他们曾经是,但主要是因为关闭功能的性能在几年前是一个已知的问题.

Mozilla说因为这个原因避免了不必要的关闭,但是闭包是JS开发人员工具箱中最强大和最常用的工具之一.

更新: 运行此测试,使用node.js(即V8,Chrome中的JS解释器)创建构造函数的1M'实例'.随着caseA = true我得到这个内存使用:

{ rss: 212291584,
vsize: 3279040512,
heapTotal: 203424416,
heapUsed: 180715856 }
Run Code Online (Sandbox Code Playgroud)

随着caseA = false我得到这个内存使用:

{ rss: 73535488,
vsize: 3149352960,
heapTotal: 74908960,
heapUsed: 56308008 }
Run Code Online (Sandbox Code Playgroud)

所以闭包函数肯定会消耗更多的内存,几乎是3倍.但从绝对意义上讲,我们只讨论每个实例约140-150字节的差异.(但是,根据创建函数时的范围内变量的数量,这可能会增加).