// Case A
function Constructor() {
this.foo = function() {
...
};
...
}
// vs
// Case B
function Constructor() {
...
};
Constructor.prototype.foo = function() {
...
}
人们建议使用原型(prototype)的主要原因之一是 .foo
在原型(prototype)的情况下被创建一次,而 this.foo
被创建多次当使用其他方法时。
然而,人们希望口译员可以优化这一点。因此在案例 A 中只有一个函数 foo
的副本。
当然,由于闭包,您仍然会为每个对象拥有一个唯一的范围上下文,但与每个对象的新函数相比,它的开销要少。
现代 JS 解释器是否优化了案例 A,因此函数 foo
只有一个副本?
最佳答案
是的,创建函数会占用更多内存。
...而且,不,解释器不会将案例 A 优化为单个函数。
原因是 the JS scope chain 要求函数的每个实例在创建时捕获可用的变量。也就是说,modern interpreters 与案例 A 相比以前是 better,但这主要是因为闭包函数的性能在几年前是一个已知问题。
Mozilla 出于这个原因对 avoid unnecessary closures 说,但是闭包是 JS 开发人员工具包中最强大和最常用的工具之一。
更新:刚刚运行了 this test,它使用 node.js(即 V8,Chrome 中的 JS 解释器)创建了 1M 个构造函数“实例”。使用 caseA = true
我得到了这个内存使用情况:
{
rss: 212291584, //212 MB
vsize: 3279040512, //3279 MB
heapTotal: 203424416, //203 MB
heapUsed: 180715856 //180 MB
}
并且使用 caseA = false
我得到了这个内存使用情况:
{
rss: 73535488, //73 MB
vsize: 3149352960, //3149 MB
heapTotal: 74908960, //74 MB
heapUsed: 56308008 //56 MB
}
所以闭包函数肯定会消耗更多的内存,几乎是 3 倍。但从绝对意义上讲,我们只是在谈论每个实例大约 140-150 字节的差异。 (但是,这可能会增加,具体取决于您在创建函数时拥有的范围内变量的数量)。
关于javascript - 创建函数是否消耗更多内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7451279/