🦅

クロージャー 内部関数は「外側を探す能力(ドア)」を最初から持っているが

に公開

① 内部関数が作られた瞬間に「スコープへのドア(参照)」は付与される

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