かすれた布
まず、クロージャーとは何ですか?これは、2つの切断されたスコープで変数を共有していると理解できます。
栗を与える:
function foo() {
var a = 10;
function bar () {
console.log(a);
}
return bar;
}
foo()();// 10 请注意这里的10怎么来的。
foo関数内の変数がグローバルスコープの下で使用されていることに気づきましたか?これはクロージャーです!!!
関数barスコープは関数fooをカバーしています。戻り値としてbar関数の参照を渡し、参照でfooの関数参照を使用できます。
クロージャ自体の魔法はここにはありませんが、一般的に、foo関数の実行が完了した後、fooのスコープはガベージコレクタによって収集されますが、fooのスコープへの参照がまだあるため、ここにはありません。渡された、つまり、bar、barにはa変数へのポインターがあるため、foo関数の使用後にfooのスコープは回復されません。barは、fooのスコープへの参照を保持しています。これは、クロージャーと呼ばれます。
さまざまな関数クロージャもあります。
function foo() {
var a = 2;
function baz() {
console.log( a ); // 2
}
bar( baz );
}
function bar(fn) {
fn(); // 妈妈快看呀,这就是闭包!
}
たぶんあなたがそれを理解した後で、クロージャーはちょっと奇妙なおもちゃですが、私が言いたいのは、クロージャーは単なる書き方ではなく、日常生活でさまざまな状況が使用されているということです。
function wait(message) {
setTimeout( function timer() {
console.log( message );
}, 1000 );
}
wait( "Hello, closure!" );
タイマーの内部スコープは1000ミリ秒後に消えず、メッセージへの参照が含まれます。
2.ループとクロージャー
for (var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
フロントエンドの他の小さな知識ポイントで、ここには変数の昇格があり、毎回6が出力されると説明しました。関数の遅延の後、RHS検索に移動してiの参照を取得するので、少し説明します。 i = 6、元々は各反復でiのコピーをキャプチャしたかったのですが、各反復は共有スコープなので、6しか見つかりません。
スコープの原則を追加してコードを変更すると、やってみましょう:
for (var i = 0; i < 5; i++) {
(function () {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
})();
}
よろしいですか?ははははは、まだ機能しない。字句スコープが空なので、彼のプライベート属性を設定する必要がある。
for (var i = 0; i < 5; i++) {
(function () {
var j = i;
setTimeout( function timer() {
console.log( j );
}, j*1000 );
})();
}
各内部無名関数の内部スコープjをポイントしているので、これは問題ありません。
このコードを美化する:
for (var i = 0; i < 5; i++) {
(function (j) {
setTimeout( function timer() {
console.log( j );
}, j*1000 );
})(i);
}
もちろん、ロジックをより簡潔に完成させたい場合は、letを使用できます。
for (let i = 0; i < 5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
モジュール
クロージャを理解したら、一般的なクロージャの使用方法を理解しましょう。
function Car() {
var name = "五菱宏光";
var age = "2 年";
function sayName () {
console.log(name);
}
function sayAge () {
console.log(age);
}
function drive () {
console.log('drived');
}
return {
sayName: sayName,
sayAge: sayAge,
drive: drive
}
}
var car = Car();
car.sayName();
これはモジュールの使用です。
このブログのアイデアの出典:(NEW)[美] -Kyle-Simpson-JavaScriptあなたが知らない(第1巻)