🦅
クロージャー 内部関数は「外側を探す能力(ドア)」を最初から持っているが
① 内部関数が作られた瞬間に「スコープへのドア(参照)」は付与される
function outer() {
let x = 1;
function inner() {
console.log(x); // ← 外を探せる
}
}
この時点で inner にはこういう情報が付いています:
- 「自分が outer の中で生まれた」という記録
- つまり “outer にアクセスできるドア(スコープ参照)”
👉 ここまではクロージャの “種” ができた状態
② しかしこのままでは外の世界から inner を呼べない
function outer() {
let x = 1;
function inner() {
console.log(x);
}
}
const f = outer();
f(); // ❌ f は undefined
inner は存在するが…
- 外に出てこない
- 呼び出す手段がない
- outer のスコープは外から閉ざされたまま
- ゆえに クロージャとして機能しない
👉 ドアはあるが、誰も持っていない状態
③ return されて「外へ持ち出されて初めて」クロージャが成立する
function outer() {
let x = 1;
function inner() {
console.log(x); // ← 外側を参照
}
return inner; // ★ ドアを持った関数を外へ渡す
}
const f = outer();
f(); // 1
ここで何が起きているかというと:
- inner(ドア付き)が外へ持ち出される
- JS エンジンは 誰かが使う可能性があるので outer のスコープを破棄しない
- f() を呼び出したとき
→ inner のドアを通って outer の変数 x にアクセスする
👉 これがクロージャが「発動」している状態
結論(あなたの理解のモデルを正式な表現にすると)
✔ 内部関数は “外側を探す能力(ドア)” を最初から持つ
= レキシカル・スコープ参照
✔ しかしそのままでは外側スコープはすぐ破棄される
= ドアは鍵のかかった部屋に置きっぱなし
✔ return(または代入など)で外へ持ち出されると初めてクロージャが成立する
= ドアを持って外の世界へ出るので、外側スコープが生き残り続ける
まとめ
内部関数は、作られたときのスコープへの参照を持つ。
return によって外へ持ち出されることで、そのスコープにアクセスする権利が生じる。
さらに内部関数が外側の変数名を参照していることによって、
外側変数へのアクセス(クロージャとしての動作)が成立する。
Discussion