くまおの森

フロントエンドで学んだこと知ったことを自分なりに噛み砕いてメモしてく技術ブログ

【JavaScript】とてもややこしいスコープチェーン

スコープチェーンについてメモします。

スコープチェーンの検索は、このように最初に発見した値を返します。

xの中身が上書きされていくということは大体想像が付きます。

処理を括るクロージャーの考えを踏まえると、
関数の外でxを呼んだ場合グローバルでxに代入したfalseが出力されます。

ここまではそんなにややこしいことはないのですが、
次の例からややこしくなっていきます。

ややこしや~

上から順に、まずグローバルで変数aに1を代入していますね。
次に変数funcにaをコンソール出力させる関数を代入してます。

次に即時関数内で、変数aに今度は100を代入させます。
※ (); ←これは関数を即時に実行させます。

次にfを実行していますが、fは引数で、
最後の行で引数に二行目で定義したfunc関数を渡しています。

ということで、即時関数内でfunc関数を実行しているわけですが、 先ほどのようにスコープチェーンの検索の仕方と、クロージャーの考えを踏まえると
同じ関数内で変数aに100を上書きしているため、コンソールで出力されるのは100じゃないかなと思います。(私はそう思いました)

ですが、ログで出力されるのはなんとグローバルで代入した1を出力するのです。

これはスコープは関数実行時ではなく、定義時に決められる為なのです。

二行目の
var func = function() { console.log(a); };

ここで定義した時点で、aはスコープチェーンの検索で一行目のvar a = 1;を見ているのです。

なので、この関数を呼び出した関数内のaはスルーされたのでした。

スコープは関数実行時ではなく、定義時に決められる

これが分かってないと出くわした際に躓いてしまいそうですね。