UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【JavaScript】クロージャと関数オブジェクト

JavaScriptクロージャと関数オブジェクトのお話を聞く機会があり、自分なりに整理してみた

先に関数オブジェクトについてまとめていたとき

uga-box.hatenablog.com

関数オブジェクトは「実行時にnamelengthをもったオブジェクトが作られる」とイメージするのが良さそうとなった

だが、実際は普通のオブジェクトでは説明ができない

例えば、以下のように外側のスコープにある変数・引数を参照するため、関数オブジェクトは自身の「環境」を知っている

let x = 1

function f (y) {
  const z = x + y
  return z
}

他にも、関数オブジェクトは関数本体を知っていたりと、ただのオブジェクトにはないプロパティが存在する

内部スロット

これを説明するために内部スロットというものを知る必要がある

これは
ECMAScriptの仕様にだけ現れるプロパティのようなもの
・JSの実行中には存在しない
 ・処理系(v8)にこういうのがあると考えると便利
 ・そのとおりに実装されているとは限らない
・通常のプロパティと区別するため二重ブラケットで囲む[[]]

関数オブジェクトの内部スロット

11個定義されている(ES2020)

https://tc39.es/ecma262/#sec-ecmascript-function-objects

f:id:uggds:20201208201108p:plain

  • [[Enviroment]]
  • [[ECMAScriptCode]]
    • 関数本体 (ボディ) への参照

関数オブジェクトの裏側には内部スロットがあって、それらが自身の「環境」や関数本体が知る理由であることがわかった