クローズドパッケージおよび関連する問題

7459 ワード

まず、閉パケットの特徴から説明すると、よりよく理解できるはずです.閉パケットの2つの特徴:1、関数変数の1つの参照として-関数が戻ると、アクティブになります.2、1つの閉パケットは、1つの関数が戻ったときに、リソースを解放していないスタック領域である.実は上の2点は1点を合成することができて、つまり閉包関数が返す時、この関数の内部の変数はアクティブな状態にあって、関数の所在するスタックの領域は依然として保留します.私達のよく知っている主流の言語、C、javaなど、関数の内部でreturnを実行するだけで、関数は結果を返しますそしてメモリからその関数が存在する領域を削除する.ライフサイクルも停止する.一般的なjs関数もそうである.しかし,閉パケット特性を持つjs関数は少し特殊である.例として,
function a(){

var i=0;

function b(){

alert(++i);

}

return b;

}

var c = a();

c();

これは標準的な閉パケットです.関数aには関数bが定義され、aはbの値をreturnします.これらは.var c=a()にかかわらず、c();この2つの実行は重要です.var c=a()です.この行では、a関数を実行すると、必ずaはreturnを通ります.主流言語の関数特性によって、現在cの値がaの戻り値です.2行目のc()の実行は実際にb関数を実行します.最後に、実行する人にかかわらず、0の値のウィンドウがポップアップされます.これまで、すべてのライフサイクルは理論的にはすべて終わりました.しかし、さらに1行多く実行すると.var c=a();c();c();1回目のポップアップ0、2回目の実行はポップアップ1.つまり、1回目のc()後もa中のiは保持されている.自然aはメモリのスタック領域に保持されている.aはreturnが過ぎているが、aおよび内部値は依然として存在し、これが閉パケットである.よし、まとめると、1、閉パケット外層は関数.2であり、閉パケット内部には関数.3があり、閉パケットはreturn内部関数である.内部関数は、外部関数の変数にアクセスします.
クローズドパッケージの適用シーン
1、関数内の変数の安全を保護する.最初の例では、関数a中のiは関数bのみがアクセスでき、他の方法でアクセスできないため、iのセキュリティが保護される.2、メモリに変数を保持します.前例のように、閉パケットでは、関数a中のiがメモリに常に存在するため、c()を実行するたびにiに1が加算される.参考资料の応用シーンによって、私达は自然にjavaあるいはc++のクラスを思い付きます.JSはクラスの概念がありませんが、クラスの似たような実行结果があります.また、もう一つのフォーマット:(function(a,b){...})(a,b);もしあなたがjqueryを使ったことがあって、そして彼のコードを見たことがあるならば、このような書き方に会って、これは匿名ですぐに関数を実行するべきです.彼の目的は、このブロック内の変数と外の変数名の衝突を避けることです.
閉パッケージと変数: 
また,役割ドメインチェーンの構成メカニズムは,閉パケットが関数中の任意の変数を含む最後の値しか取得できないというもう一つの問題を引き起こした.閉パッケージには、特定の変数ではなく変数オブジェクト全体が保存されます.次のようになります.
function create(){

  var result = [];

  for(var i=0;i<10;i++)

  {

     result[i]=function(){

        return i;

     };

  }
return result; }

resultの関数を実行した結果はすべて10.この問題を回避する必要がある場合は、次のように変更できます.
function create(){

  var result = [];

  for(var i=0;i<10;i++)

  {

     result[i]=function(num){

        return function(){

            return num;

        };

     }(i);

  }

  return result;

}

もう一つ似たような栗:
var obj={};

var events={"m1":"changed","m2":"clicked"};

for(var attr in events)

{

   obj[attr]=function(){

         alert(events[attr]);

   };

}



alert(obj["m1"]==obj["m2"];);//false

obj["m1"]();//"clicked"

obj["m2"]();//"clicked"

 
 
閉じてthis:
 閉パッケージでthisを使用しても問題が発生します.このオブジェクトは、実行時に関数に基づく実行環境にバインドされます.
var name="The Window";

var myObject={

  name:"My Object",

  sayNameFunction:function(){

    return function(){

      return this.name;

    };

  }

};



alert(myObject.sayNameFunction()());//The Window

解決策はthisオブジェクトを保存することです.
var name="The Window";

var myObject={

  name:"My Object",

  sayNameFunction:function(){

    var that = this;

    return function(){

      return that.name;

    };

  }

};



alert(myObject.sayNameFunction()());//My Object

 
 静的プライベート変数
(function(){

  var name;

  Person=function(value){

    name=value;

  };

  Person.prototype.getName=function(){

    return name;

  };

  Person.prototype.setName=function(value){

    name=value;

  };

})();



var person1=new Person("Rose");

person1.setName("Mike");

alert(person1.getName());//Mike



var person2=new Person("Van");

alert(person1.getName());//Van

alert(person2.getName());//Van

nameは静的プライベート変数に相当し,各インスタンスによって共有される.