11

在 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

但是您可以通过使用局部变量并使用闭包作为吸气剂来模拟“私有”字段:

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

一个区别是,对于“公共”方法,每个实例的 getter 都是同一个函数对象:

console.assert(t1.getPublicX === t2.getPublicX);

而对于“私有”方法,每个实例的 getter 都是一个不同的函数对象:

console.assert(t1.getPrivateX != t2.getPrivateX);

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

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

Jsperf

4

1 回答 1

6

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

我的意思是:

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

var t2 = new Test();

t1.getPublicX(); // Returns true
t2.getPublicX(); // Returns 15

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

我还应该补充一点, and in 的概念publicprivateinjavascript完全不同C++。在C++私有中封装了成员,只能从类中访问,javascript您仍然可以从任何地方访问该成员。

在运行一个简短的测试之后,开销实际上是微不足道的。该选项卡比没有它的情况下多 40mb(加载了谷歌),如下面的屏幕截图所示:

在此处输入图像描述

链接到全尺寸图像。

于 2012-12-04T19:25:21.560 回答