【问题标题】:Will javascript private members in classes cause a huge memory overhead?类中的 javascript 私有成员会导致巨大的内存开销吗?
【发布时间】:2012-12-04 18:59:26
【问题描述】:

在 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

但您可以通过使用局部变量并使用闭包作为 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

【问题讨论】:

  • 公共和私有方法都是线性的 - O(n) - 在资源消耗方面(只是 C 不同)。由于它最终是一个实现细节,因此了解它是否“[使用过多]内存开销”的唯一方法是运行一些测试。对于 已知 有 10k+ (100k+?) 个实例的对象,我会首先选择仅​​原型方法;这是我自己未经证实的“表现”强加。但同样,这都是线性增长。
  • (我投了赞成票,因为我认为从不同的 ECMAScript 实现获得经验证据的答案会很好。 )
  • @ruakh 你对命名是正确的,但这是公开私人成员的唯一方法。

标签: javascript


【解决方案1】:

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

我的意思是:

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

var t2 = new Test();

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

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

我还应该补充一点,javascript 中的publicprivate 的概念与C++ 中的概念完全不同。在C++ 中,private 封装了只能从类内部访问的成员,而在javascript 中,您仍然可以从任何地方访问该成员。

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

Link to full size image.

【讨论】:

    猜你喜欢
    • 2017-12-20
    • 1970-01-01
    • 2016-12-12
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多