关于JavaScript中关闭/封装效率的问题

时间:2011-06-13 13:59:55

标签: javascript oop performance closures

我对JavaScript很新,所以如果这是一个愚蠢的问题,请耐心等待。

让我们说我有一个看起来像这样的“课堂”:

var obj = function () {
    var val;
    return {
        setVal: function(newVal) {
            val = newVal;
        },
        getVal: function() {
            return val;
        }
    };
};

假设我的语法正确,它定义了一个名为“value”的“private”属性的类,其中包含设置/获取属性的方法。现在,我将从这个类中创建两个对象:

var myObj = obj();
var yourObj = obj();

这会为每个对象创建一个单独的setVal()和getVal()方法吗?如果没有,为什么不呢?如果是这样,在构建高效的Web应用程序时这是一个严重问题吗?在大多数/所有情况下,关闭效率的权衡(如果有的话)是否值得?我笨吗?

谢谢, 杰拉德

2 个答案:

答案 0 :(得分:3)

var obj = function () {
    var val;
    return {
        setVal: function(newVal) {
            val = newVal;
        },
        getVal: function() {
            return val;
        }
    };
};

这个功能的作用如下:

  • 创建名为val
  • 的变量
  • 创建新对象
  • 创建一个新功能并将其分配到字段setVal
  • 创建一个新功能并将其分配到字段getVal
  • 返回对象。

所以你总是创造4件新事物。

如果页面上的对象少于1000个,则这不是一个真正的问题。重构它是一种微观优化。

另一种方法是不依赖局部变量,并使用this._val表示val是私有的。

答案 1 :(得分:0)

它确实在概念上这样做。但是,由于这是一种常见的模式,现代JavaScript JITers知道如何优化它,以便只有一个代码副本存储在内存中,并使用适当的指针重定向使其适用于相关的闭包。

编辑:虽然我不是真的想通过源代码进行深思熟虑,但这里有一些基本的证据。 Download the Chrome dev channel release,并在运行以下代码之前和之后获取堆快照:

var obj = /* as above */;

var objs = [];
for (var i = 0; i < 10000; ++i) {
    objs.push(obj());
}

然后对此代码执行相同的操作:

function Obj() { }
Obj.prototype.setVal = function (value) { this._val = value; };
Obj.prototype.getVal = function () { return this._val; };

var objs = [];
for (var i = 0; i < 10000; ++i) {
    objs.push(new Obj());
}

在这两种情况下,您都会发现堆快照显示“代码”的相同数字,所以我所描述的优化确实正在执行。