閉鎖の概念
関数内で内部関数を定義し、内部関数を返します。外部関数が実行された場合でも、外部関数を参照する内部関数の変数はメモリに保存されます。これらの変数のコレクションをクロージャと呼びます(またはターンクロージャへの内部関数)。
一部の人々はまた、クロージャの概念を次のように定義しています。関数内に関数を定義すると、この内部関数は「クロージャ」と呼ばれます。
function f1(){
var a1=1;
function f2(){
console.log(a1)
}
return f2
}
let result=f1()
result();//1
f2はクロージャと呼ばれます
クロージャの役割
- クロージャを通じて、外部環境は関数内の変数にアクセスできます
- f1のf2によってアクセスされる変数は、常にメモリに保存されます。f2の専用可変バックパックを形成します。
- クロージャを使用すると、内部関数変数は外部変数を汚染せず、競合を回避します
クロージャーの副作用
- 変数はメモリ内に存在し、メモリオーバーフローを引き起こすため、使用しないときは変数を空にすることを忘れないでください。
- 解決策:使用していないときは変数をクリアすることを忘れないでください
実行環境とスコープチェーン
クロージャを理解するには、まずjsの実行環境とスコープを理解する必要があります
- 各関数には実行環境があり、実行環境は変数オブジェクトに関連付けられています。変数オブジェクトのコレクションはスコープチェーンと呼ばれます。
- スコープチェーンのフロントエンドは、現在の実行コードが配置されている変数オブジェクトであり、次のオブジェクトは、グローバル変数に続く外部関数です。
- 識別子の解決は、スコープチェーンに沿ってフロントエンドから段階的にバックトレースするプロセスです。
- コードが実行されると、コードが配置されている環境が破棄されます。Webのグローバル実行環境はウィンドウオブジェクトであり、アプリケーションが終了するとグローバル環境が破棄されます。
クロージャの適用
imgオブジェクトは、次のようにデータレポートによく使用されます。
var report = function(src) {
var img = new Image();
img.src = src;
}
report('http://xxx.com/xxx.png');
このコードを実行すると、一部の低バージョンブラウザにバグがあり、一部のデータが報告されます。その理由は、imgがレポート関数のローカル変数であるためです。レポート関数が呼び出された後、 imgオブジェクトはすぐに破棄され、これはhttpリクエストを送信する時間がない可能性があるため、このリクエストは失われます。
解決策:したがって、クロージャーを使用してimgオブジェクトを閉じ、データ損失の問題を解決できます。
var report = (function() {
var imgs = [];
return function(src) {
var img = new Image();
imgs.push(img);
img.src = src;
}
})()
(function(){
//i在外部就不认识啦
for(var i=0;i<count;i++){
}
})();
console.log(i);//报错,无法访问