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

1 つの違いは、「パブリック」アプローチでは、各インスタンスのゲッターが同じ関数オブジェクトであることです。

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

一方、「プライベート」アプローチでは、各インスタンスのゲッターは個別の関数オブジェクトです。

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

このアプローチのメモリ使用量に興味があります。各インスタンスには個別getPrivateXの があるため、たとえば 10,000 個のインスタンスを作成すると、メモリのオーバーヘッドが大きくなりますか?

プライベート メンバーとパブリック メンバーを持つクラスのインスタンスを作成するパフォーマンス テスト:

Jsperf

4

1 に答える 1

6

もちろん、メモリのオーバーヘッドが発生します。公開の場合、関数はインスタンスではなくに属しprototypeます。つまり、特定のオブジェクトにその関数の独自のインスタンスを具体的に与えない限り、インスタンスは 1 つしかありません。非公開の場合、関数はインスタンスに属します。つまり、メモリ管理を実行する必要があります。

これが意味することは次のとおりです。

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

var t2 = new Test();

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

そのため、パブリックメンバーでも同じ状況になる可能性があります。一般的に、あなたの質問に対する答えは次のとおりです。はい、多数のオブジェクトをインスタンス化するときにメモリのオーバーヘッドがあります。

publicまた、 and privateinの概念は injavascriptとまったく同じではないことも付け加えておきC++ます。C++プライベートでは、クラス内からのみアクセスできるようにメンバーをカプセル化します。これにより、javascriptどこからでもメンバーにアクセスできます。

短いテストを実行した後でも、オーバーヘッドは実際には重要ではありません。以下のスクリーンショットに示すように、タブは、タブがない場合よりも 40 MB 多く (Google が読み込まれている場合) 使用します。

ここに画像の説明を入力

フルサイズの画像へのリンク。

于 2012-12-04T19:25:21.560 に答える