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

标签 javascript v8 spidermonkey

// 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/

相关文章:

javascript - 关闭按钮会在 Chrome 扩展程序弹出窗口中打开新的 chrome 商店选项卡

node.js - 在 Node.js 中何时使用 next() 并返回 next()

javascript - 什么时候在 Node.js V8 中分配和编译闭包?

javascript - 预期的不合格 ID cstdlib

CouchDB - 跨 View 、跨设计文档、跨数据库共享功能

JavaScript 专家 : Do block-scopes with `{}` and anonymous functions both help garbage-collection?

javascript - Crossfilter 中的自定义计算聚合字段

javascript - 将 id 解析为 Bootstrap 模式

javascript - AngularJS,ng-repeat with ng-include 不呈现

javascript - 使用 "using strict"作为 "use strong"的备份