2016-03-29 8 views
1

を持つObjectsを初期化するコンストラクタが必要です。私はこのようなコードを書く:静的プライベートフィールドJavascript

Obj.prototype.idCounter = 0; 
Obj = function() { 
    this.name = "Obj_" + Obj.prototype.idCounter; 
    Obj.prototype.idCounter++; 
} 

var o1 = new Obj(); 
var o2 = new Obj(); 
alert(o1.name); // Obj_0 
alert(o2.name); // Obj_1 

しかし、Obj.prototype.idCounterは非公開です。私はプライベート変数を作成する方法を知っていますが、プライベートな静的変数を作る方法はわかりません。あなたは何ができるか

+1

さて、実際にはjavascriptは、古典的なオブジェクト指向言語にマップすることはできません。プロトタイプ指向です。だから短い答え:申し訳ありませんが、あなたはできません。 – axelduch

+0

Symbol機能を導入することで、偶発的なプロパティ衝突の脅威に対してより堅牢なコードを作成することが可能になりますが、 'Object.getOwnPropertyNames()'と ' Object.getOwnPropertySymbols() 'いくつかの目的のために、クロージャを使用することができます。 – Pointy

+0

こんにちは、ちょうどここで学ぼうとしています。クロージャはプライベート変数をどのように作成するのですか?プライベート変数を静的にすることはjsでは不可能だと言っていますか? – Observer

答えて

3

はこれです:今

var Obj = function() { 
    var idCounter = 0; 

    function Obj() { 
     this.name = "Obj_" + idCounter; 
     idCounter++; 
    } 
    return Obj; 
}(); 

idCounterはその匿名関数のローカル変数なので、他には何もコンストラクタ関数を除いて、それを見ることはできません。あなたもそこにあまりにもでプロトタイプオブジェクトのいくつかの初期化を行うことができます

注:OBJのインスタンスを持っているとき

var Obj = function() { 
    var idCounter = 0; 

    function Obj() { 
     this.name = "Obj_" + idCounter; 
     idCounter++; 
    } 
    // one way to add a prototype property, and not 
    // the simplest 
    Object.defineProperties(Obj.prototype, { 
     getInstanceCount: { 
     value: function() { 
      return idCounter; 
     } 
     } 
    }); 
    return Obj; 
}(); 

を今あなたはどのだろう(作成されたオブジェクトの合計数を取得するためにgetInstanceCount()を呼び出すことができますAPIを設計するには奇妙な方法ですが、プロトタイプ関数がそれらのprivate変数にもアクセスできるかもしれないことを説明するだけです)。

+1

@axelduchいいえ - 別のバージョンを持つのは良いことです。 – Pointy

+0

'Object.defineProperties'を使って簡単なメソッドを割り当てるのはなぜですか? – Bergi

+0

@Bergi嬉しいことに頼んだよ! :)私は、プロトタイプ関数を定義する習慣には、いくつかの理由から、プロトタイプの奇妙さを少なくするためにも、Object.keys() ')クリーン。それは個人的な影響ですが、私がこのコードを入力したときに私は実際にそれについて多くのことを考えなかったので、私が試みてきた自己洗脳が明らかに働いていたことを意味します。 – Pointy

3

プライベート静的メンバーを記述した方法でレプリケートする方法はありません(私が知る限り)。

idジェネレータを安全に保つという問題を解決するには、モジュールパターンを使用し、モジュールスコープ内から特権アクセスを使用することができます。

// using an immediately invoked function to generate the isolated scope 
var Obj = (function() { 
    var idCounter = 0; 

    return function Obj() { 
     this.name = "Obj_" + idCounter; 
     idCounter++; 
    }; 
}()); 

var o1 = new Obj(); 
var o2 = new Obj(); 
alert(o1.name); // Obj_0 
alert(o2.name); // Obj_1 
0

JavaScriptでは、通常、フィールド名の先頭にアンダースコア_を付けて、プライベートであることを示します。もちろん、これはそれらを本当にプライベートにするものではありませんが、開発者はいくつかの自己規律を示し、それを非公開とみなすべきです。

function Obj() { 
 
    this.name = "Obj_" + (Obj._idCounter++); 
 
} 
 
Obj._idCounter = 0; 
 

 
var o1 = new Obj(); 
 
var o2 = new Obj(); 
 
log(o1.name); // Obj_0 
 
log(o2.name); // Obj_1 
 

 
function log(x) { var p = document.createElement('pre'); p.appendChild(document.createTextNode(x)); document.body.appendChild(p); }

他の人が述べたように、あなたは本当に、あなたはもちろんの使用クロージャのことができる何かを非表示にしたい場合。しかし、デバッグするのが少し難しく、何らかの理由でそれがbit slowerです。

関連する問題