jsのクローズド匿名関数とスコープに関するいくつかの小さな点

3526 ワード

今日はjsの閉め切った章を見ました.例によって作られた頭が大きいです.
まず、クローズド中の自由変数についてです.
var result=[];
function foo(){
    var i= 0;
    for (;i<3;i=i+1){
        result[i]=function(){
            alert(i)
        }
    }
};
foo();
result[0](); // 3
result[1](); // 3
result[2](); // 3
このコードの中で、プログラマはfoo関数の変数iを内部循環の関数で使用し、それぞれインデックスを得ることができますが、実際には、変数が最後に残した値しか得られません.つまり、クローズドに記録されている自由変数は、変数の値ではなく、この変数の1つの参照にすぎません.この変数が変更されたとき、クローズドに取得した変数の値は、変えられます
解決の方法の一つは、内部関数をループ作成時に直ちに実行させ、現在のインデックス値をキャプチャーし、自分のローカル変数に記録します.戻り関数の方法を利用して、内部関数を書き換えて、次の呼び出し時にローカル変数の値を返します.
var result=[];
function foo(){
    var i= 0;
    for (;i<3;i=i+1){
        result[i]=(function(j){
            return function(){
                alert(j);
            };
        })(i);
    }
};
foo();
result[0](); // 0
result[1](); // 1
result[2](); // 2
上記のコードは匿名関数を使って直ちに実行されます.
var fnName=function(){
    alert('Hello World');
}();//         , javascript               
そのうちf(num){}(i);は、外部変数iをnumに値付けし、iが内部にあることを心配しなくても大丈夫です.
次いで7.2.2の例である.
var name = "The window";

var object = {
    name: "My Object";
    getNameFunc: function(){
        return function(){
            return this.name;
        };
    }
};

alert(object.getNameFunc()());  //     The window
上記のコードの中でgetName Funnc関数内で匿名関数を返しました.jsの匿名関数thisはずっとwindowを指しています.これを理解すれば、なぜ最後の結果がThe windowなのかが分かります.