一体何がクローズドですか?javascriptの閉鎖を深く理解する

2513 ワード

古い定義
  (closure),                 ,           “  ”   。
//    ,           
function foo() {
    var a = 0;
}
cosole.log(a) 
// Uncaught ReferenceError: a is not defined

「JavaScript高級プログラム設計」によるクローズド定義
クローズドとは、別の関数のスコープにアクセスする権限を持つ変数の関数です.
 //  《JavaScript      》,                   
function foo() {
    var a = 2;
    function bar() {
        console.log(a);
    }
    bar();
}
foo();
「JavaScript権威ガイド」は、クローズドの定義について
関数オブジェクトは、作用ドメインチェーンを介して相互に関連し、関数の内部変数は関数の作用領域に保存できます.
 var global = "global scope"; //    
function checkscope() {
    var scope = "local scope"; //    
    function f() {
        return scope; //          
    };
    return f();
}
checkscope(); //    "local scope"
厳密には、クローズドは3つの条件を満たす必要があります.【2】関数ネスト;【3】在地域外で呼び出された場合、条件1だけでいいという人もいますので、IIIFSEは閉包です.ある人は条件1と2を満たすと思っています.だから、入れ子された関数は閉じられています.3つの条件が全部満たされていると思っている人もいますので、スコープ以外のところで呼び出された関数はクローズドです.
なぜ私達は鞄を閉じる必要がありますか?
まず一例を見て、カウンタを実現します.
var counter = 0;
function add() {
   return counter += 1;
}
add();
add();
add();//        3 
今は目的を達成しましたが、問題が来ました.コードのどの関数でも勝手にカウンタの値を変えることができますので、このカウンタは完璧ではありません.counterをadd関数に置いたらいいじゃないですか?
function add() {
    var counter = 0;
    return counter += 1;
} 
add();
add();
add();//        3,        1
したがって、add関数を呼び出すたびに、counterの値を0に初期化しますか?それとも目的に達しません.
クローズドの使い方
ですから、この時はクローズドでこの問題を解決します.まずコードを見ます.
var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();
add();
add();
add();//      3
この時、私たちは完璧にカウンターを実現しました.この部分は非常に簡潔で、以下の等価コードに分割することができる.
function outerFunction () {
     var counter = 0;
     function innerFunction (){
         return counter += 1;
     }
     return innerFunction;
}
var add = outerFunction();
add();
add();
add();//      3
この時のaddは一つのクローズドを形成しました.一つのクローズドは二つの部分からなり、関数とその関数を作成する環境です.環境は環境における局所変数から構成される.クローズドaddは関数innerFunctionと変数counterから構成されていますので、このときaddは変数counterにアクセスできます.
クローズドを使うときの注意点
クローズドはその関数を含むスコープを携帯するので、他の関数よりも多くのメモリを占有します.したがって、メモリを解放するために、匿名関数への参照を手動で解除することができる.
function f2(){
    var n=22;
    var nAdd=function(){n++};
    return function(){
        return {
            n:n,
            nAdd:nAdd
        }
    }
}
//result2           
var result2=f2();
//    
console.log(result2());
result2().nAdd();
console.log(result2());
//          ,      
result2=null;
  • 1