クロージャーの定義
クロージャは、組み合わされた(囲まれた)関数と、その周囲の状態(レキシカル環境)への参照の組み合わせです。言い換えれば、クロージャは内側の関数から外側の関数スコープへのアクセスを提供します。JavaScript では、関数が作成されるたびにクロージャが作成されます。by_MDN意味がわかりません。順を追ってみていきましょう。
クロージャーを理解するために理解するべきこと4つ
1: JavaScriptは関数の中に関数を定義できる
```javascript function hello() { function child() { console.log("helloの子供だよ") } return child; }console.log(hello());
//コンソール
ƒ child() {
console.log("hello の子供だよ")
}
hello()を実行すると戻り値として、child関数を返しているため、コンソールのような結果になります。
普段JavaScriptを書いている方であれば、普通にやっていることですよね。
<h5>2: JavaScriptの関数は変数として持ち運べる</h5>
```javascript
const x = hello()
console.log(x)
//コンソール
ƒ child() {
console.log("helloの子供だよ")
}
先ほど実行した hello()関数をそのまま変数に入れてしまうことができます。
もちろんコンソールは変数に入れただけですので、同じ結果になります。
この変数 x に入った関数を実行すると
x();
//コンソール
helloの子供だよ;
といった具合になります。
そして、変数としても運べるということは、引数として利用することもできます。
引数を一つ受け取る関数を用意し、変数に格納された関数を渡してみます。
function receive(v) {
console.log('引数で受け取ったvを実行するよ');
v();
}
receive(x);
//コンソール
引数で受け取ったvを実行するよ;
helloの子供だよ;
ここまでが JavaScript の関数は変数として持ち運べるの説明になります。
3:JavaScriptの関数は親の関数の変数を扱える
前提として一方の関数からほかの関数の変数を使うことはできません
function suda() {
const masaki = '菅田将暉';
}
function komatsu() {
console.log(masaki);
}
komatsu();
//コンソール
エラー;
しかし関数が親子関係にある場合、子供の関数は、親の変数を使うことができます。
この場合、親が suda()で子供が komatsu()になります。(本当は夫婦なんですけどね)
※親が子供の変数を使うことはできません
function suda() {
const masaki = '菅田将暉';
function komatsu() {
const nana = '小松奈菜';
console.log(masaki);
console.log(nana);
}
komatsu();
}
suda();
//コンソール
菅田将暉;
小松奈菜;
4:JavaScriptの関数の親は生みの親のことである
言葉の定義
・ダイナミックスコープ
関数を実行するときの親を親とする
・レキシカルスコープ
自分を定義した関数を親とする
関数の親の決め方には、上記の二種類があって、JavaScript はレキシカルスコープを採用している。
例えば、このような親子関係の関数があります。
function suda() {
const masaki = '菅田将暉';
function komatsu() {
const nana = '小松奈菜';
console.log(masaki);
console.log(nana);
}
return komatsu;
}
komatsu()関数の親は suda()関数です。
次に suda()関数を実行し、戻り値である komatsu()関数を変数 suda_return に格納します
function receive(v) {
const masaki = '相葉雅紀';
v();
}
const suda_return = suda();
receive(suda_return);
//コンソール
菅田将暉;
小松奈菜;
レキシカルスコープの定義を見ると「自分を定義した関数を親とする」とあります。
receive()関数の引数 v()関数の中身を見ると
function receive(v) {
const masaki = '相葉雅紀';
function komatsu() {
const nana = '小松奈菜';
console.log(masaki);
console.log(nana);
}
komatus();
}
となっており変数 masaki には相葉雅紀が入りそうですが、これは自分を定義した関数ではありません。
従って、コンソールには komatus()関数を定義した親にあった masaki の変数に入っていた菅田将暉が現れるわけです。
そして、初めの意味わからなかったクロージャを簡単にした説明は、
「関数と生みの親(祖先含め全員)が持っている変数を合わせてクロージャと呼ぶ」
----------追記予定----------