JavaScriptのクロージャのサンプルです。
クロージャ
- 関数の中に関数が定義してあります。
- 外側にある関数がエンクロージャで内側にある関数がクロージャです。
- 外側の関数が実行された時点で内側の関数のインスタンスの参照を返します。
- 参照を持つことで、作成された環境(変数)を覚えています。
- 以下は、MDNのクロージャのリンクです。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures
クロージャのサンプルです。
<script>
function test1() { //エンクロージャ
let i = 0;
return function () { //クロージャ
let x = ++i; //1を加えて値を返す
console.log(x);
};
}
var f1 = test1();
console.log(f1);
//ƒ (){ //クロージャ
// let x = ++i; //1を加えて値を返す
// console.log(x);
// }
var f2 = test1();
f1(); // 1
f2(); // 1
f1(); // 2
f2(); // 2
f1 = "a";
//f1(); //エラー f1 is not a function
var f1 = test1();
f1(); // 1
</script>
2-8行目は、関数の中に関数があります。
2行目が外側の関数でエンクロージャです。
4行目が内側の関数(無名関数)でクロージャです。無名関数をreturnしています。
10行目のtest1()の実行は、内側の関数のインスタンスの参照を返し変数f1に代入します。
11行目は、returnされた無名関数の内容(12-15行目)を表示しています。
16行目のtest1()の実行も、内側の関数のインスタンスの参照を返します。今度は別の変数f2に代入しています。
18-21行目は、それぞれ関数を実行していますが、それぞれ別でカウントされます。
f1とf2は同じ関数本体の定義を共有していますが、保有している環境は異なります。
23行目は、変数f1にaを代入して関数のインスタンスの参照を消しています。
24行目は、関数を実行しようとしますが参照先がないのでエラーになります。(f1 is not a function)
26行目は、再度test1()を実行して、内側の関数のインスタンスの参照を返し変数f1に代入します。
27行目は、新たに生成するので1が表示されます。
関連の記事
JavaScript 関数宣言と関数式のサンプル
JavaScript 関数式と無名関数と即時関数
JavaScript 引数/戻り値が関数のサンプル(高階関数)