コードは次のとおりです:
//静的プライベート変数とインスタンスプライベート変数
(function () {
//プライベート変数を定義します
var staticPrivateValue = "";
//コンストラクター、コンストラクターweaving function to a global variable
MyObject = function (name) {
//インスタンス変数を定義します
this.name = name
}//プライベートにアクセスするための 2 つのパブリック メソッドを定義します。変数をプロトタイプに再度追加します。
MyObject.prototype.getPrivateValue = function () {
return staticPrivateValue;
}
MyObject.prototype.setPrivateValue = function (value ) {
staticPrivateValue = 値;
}
})();
var mo = new MyObject("jeff-gyy");
mo.setPrivateValue("gyycyy"); private 属性
alert(mo.getPrivateValue()); // 出力 gyycyy
alert(mo.name); // 出力 jeff-gyy
var mo1 = new MyObject("jeff- cyy");
alert(mo1.getPrivateValue()); //gyycyy を出力
alert(mo1.name); //jeff-cyy を出力
上記のコードから返される値を見てください。 mo1 が getPrivateValue 関数を呼び出すと、mo によって設定された値が「gyycyy」になるのはなぜですか?まず、匿名関数を定義し、その関数にプライベート変数 staticPrivateValue が含まれていると、MyObject に対して定義された 2 つのプロトタイプ メソッドが、クロージャのスコープ チェーンを通じて実際にその関数内のプライベート変数にアクセスできます。 getPrivateValue と setPrivateValue 両方の関数のスコープ チェーンには匿名関数の変数オブジェクトが含まれているため、スコープ チェーンに含まれる変数オブジェクトは実際にはポインターであることがわかっているため、作成された 2 つのオブジェクトはパブリック メソッドを使用してプライベート変数を格納します。これは、匿名関数の変数オブジェクト内の staticPrivateValue であるため、変数インスタンス間で共有できます。従来の OO 言語の観点から見ると、私たちが実装する静的プロパティは、実際には本当の意味で静的ではなく、静的プロパティのインスタンスの共有を実現するだけです。
. モジュール モードと拡張モジュール モード
データをグローバルに共有するもう 1 つの方法は、モジュール モードを使用してオブジェクト タイプのシングルトン モードを実装することも、拡張モジュール モードを使用することもできます。次の例に示すように、タイプのシングルトン パターンを実装します。
//Define コンストラクター var mo = new function () {
//プライベート変数
var privateValue = ""
//通常のモジュール モード
; return {
publicValue: "public ",
//プライベート変数にアクセスします
getPrivateValue: function () {
return privateValue;
},
setPrivateValue: function (value) {
privateValue = 値;
}
}();
mo.setPrivateValue("プライベート値");
alert(mo.getPrivateValue()); (mo.publicFunction());
モジュール モードは、匿名関数を使用して内部実装をカプセル化します。この例では、返されたオブジェクトにプライベート変数 privateValue が含まれています。クロージャのスコープ チェーンを介して含まれる関数にアクセスします。定義された匿名関数はすぐに呼び出されるため、変数 mo は返されたオブジェクトを参照します。上記のシングルトン パターンは、Object オブジェクトを返します。拡張モジュール パターンを使用して、カスタム タイプのシングルトン パターンを実装できます。 > コードは次のとおりです:
//拡張モジュール モード
//カスタム コンストラクター
function MyObject(name) { o.publicValue = "public"; //プライベート変数にアクセスしますo.getPrivateValue = function () {
return privateValue; o.setPrivateValue = 関数 (値) {
privateValue = 値;
return o;
mo.setPrivateValue("プライベート値"); (mo.getPrivateValue());
alert(mo.publicFunction());
上記のコード例は、MyObject のシングルトン モードを実装しています。
最後に言及する必要があるのは、クロージャの使用には利点と欠点があるということです。クロージャのスコープ チェーンは関数を含む変数オブジェクトを参照するため、追加のメモリを占有し、変数の検索も必要になります。スコープチェーンを介して実行されるため、検索時間が消費され、クロージャが深くなるほど状況はより深刻になります。さらに、IE (以前のバージョン) では、ガベージ コレクション メカニズムで参照カウントが使用されるため、次の例に示すように、循環参照が発生してメモリ リークが発生する可能性があります:
コードをコピーします
コードは次のとおりです。
function assignHandler(){
var element = document.getElementById("someElement"); element.onclick = function( ){
alert(element.id)
}
;
上記のコードでは、要素のイベントとしてクロージャが作成されています。クロージャは、関数 assingHandler を含む変数オブジェクトへの参照であるため、要素の参照カウントが 1 になります。リサイクルされないため、メモリ リークが発生します。それを修正する方法を考えることができます。