JavaScriptの最も重要な機能の1つは、閉鎖の使用です。閉鎖の使用により、現在のスコープは常に外部スコープにアクセスできます。 JavaScriptにはブロックレベルの範囲がなく、関数範囲のみであるため、閉鎖の使用は関数に密接に関連しています。
プライベート変数をシミュレートします
コードコピーは次のとおりです。
function counter(start){
var count = start;
戻る {
増分:function(){
count ++;
}、
get:function(){
返品数;
}
}
}
var foo = counter(4);
foo.increment();
foo.get(); // 5
ここで、カウンターは2つの閉鎖を返します:関数の増加と取得。これらの2つの関数は、カウンタースコープへのアクセスを維持するため、カウントスコープで定義されている変数カウントにアクセスできます。
私的変数の作業メカニズム
JavaScriptは値と参照をスコープに割り当てることができないため、上記の例では、外部から内部のプライベート変数カウントに直接アクセスする方法はありません。唯一の方法は、閉鎖を定義してアクセスすることです。
コードコピーは次のとおりです。
var foo = new Counter(4);
foo.hack = function(){
count = 1337;
};
上記のコードは、ハックがカウンター内で定義されていないため、カウンタースコープ内のカウント変数の値を変更しません。上記のコードは、グローバル変数カウントのみを作成または上書きします。
ループ内の閉鎖
最も簡単な間違いの1つは、ループ内で閉鎖を使用することです。
コードコピーは次のとおりです。
for(var i = 0; i <10; i ++){
setimeout(function(){
console.log(i);
}、1000);
}
上記のコードは0〜9に出力されませんが、10倍連続して出力されます。
上記の匿名性は、変数iへの参照を保持します。 Console.log関数が出力を開始するために呼び出されると、これは終了したループであり、変数Iはすでに10です。
上記のエラーを回避するには、ループするたびに値の変数のコピーを作成する必要があります。
引用符は避けてください
ループ内の変数の値をコピーするには、最良の方法は、匿名関数を外層に追加してすぐに実行することです。
コードコピーは次のとおりです。
for(var i = 0; i <10; i ++){
(function(e){
setimeout(function(){
console.log(e);
}、1000);
})(私);
}
この外部匿名関数は、ループ変数Iを最初のパラメーターとして取得し、その値を独自のパラメーターeにコピーします。
外部匿名関数はパラメーターEをSettimeOutに渡すため、SettimeOutにはパラメーターeへの参照があります。さらに、このパラメーターEの値は、外部ループの変更により変更されません。
同じ効果を達成する別の方法があります。これは、Settimeoutの匿名関数の匿名関数を返すことです。
コードコピーは次のとおりです。
for(var i = 0; i <10; i ++){
setimeout((function(e){
return function(){
console.log(e);
}
})(i)、1000)
}
さらに、BINDメソッドを使用して達成することもできます。
コードコピーは次のとおりです。
for(var i = 0; i <10; i ++){
setimeout(console.log.bind(console、i)、1000);
}
記事の最後に、要約しましょう。
(1)閉鎖は設計原則です。コンテキストを分析することでユーザーの呼び出しを簡素化し、ユーザーがそれを知らずに目的を達成できるようにします。
(2)閉鎖の分析に関する主流のオンライン記事は、実際には閉鎖原則に反しています。閉鎖の詳細を適切に使用する必要がある場合、この閉鎖は設計の失敗です。
(3)できるだけ学習しないようにしてください。