类中的javascript私有成员会导致巨大的内存开销吗?

xia*_*oyi 11 javascript

在JavaScript中,对象的字段始终是"公共的":

function Test() {
  this.x_ = 15;
}
Test.prototype = {
  getPublicX: function() {
    return this.x_;
  }
};
new Test().getPublicX();       // using the getter
new Test().x_;                 // bypassing the getter
Run Code Online (Sandbox Code Playgroud)

但您可以使用局部变量并使用闭包作为getter来模拟"私有"字段:

function Test() {
  var x = 15;
  this.getPrivateX = function() {
    return x;
  };
}
new Test().getPrivateX();       // using the getter
// ... no way to access x directly: it's a local variable out of scope
Run Code Online (Sandbox Code Playgroud)

一个区别是,使用"公共"方法,每个实例的getter都是相同的函数对象:

console.assert(t1.getPublicX === t2.getPublicX);
Run Code Online (Sandbox Code Playgroud)

而使用"私有"方法,每个实例的getter都是一个独特的函数对象:

console.assert(t1.getPrivateX != t2.getPrivateX);
Run Code Online (Sandbox Code Playgroud)

我很好奇这种方法的内存使用情况.由于每个实例都有一个单独的getPrivateX,如果我创建10k个实例,这会导致巨大的内存开销吗?

使用私有和公共成员创建类实例的性能测试:

Jsperf

Kon*_*nev 6

当然会产生内存开销.在公共情况下,您的函数属于prototype非实例,这意味着只有一个实例,除非您专门为特定对象提供它自己的该函数实例.在私有情况下,该函数属于实例,这意味着您需要执行内存管理.

我的意思是:

var t1 = new Test();
t1.getPublicX = function () {
    return true;
}

var t2 = new Test();

t1.getPublicX(); // Returns true
t2.getPublicX(); // Returns 15
Run Code Online (Sandbox Code Playgroud)

因此,您也可以与公共成员处于同样的境地.一般来说,您的问题的答案是:是的,在实例化大量对象时会产生内存开销.

我还要补充一点的概念public,并privatejavascript一点也不一样C++.在C++私有中封装成员只能从类中javascript访问,您仍然可以从任何地方访问该成员.

在进行简短的测试之后,开销实际上是微不足道的.该标签需要40多个(加载谷歌)而不是没有它,如下面的屏幕截图所示:

在此输入图像描述

链接到完整尺寸的图像.