こういうコードを書くと
var hoge = 0; function func1(){ console.log(hoge); } function func2(){ var hoge = 100; var func2_1 = function(){ console.log(hoge); } func2_1(); } function func3(){ var hoge = 100; func1(); } func1(); func2(); func3();
こんな風に動きます。
func1は当然グローバルのhogeを拾ってきます。
func2も当然一つ上のスコープのhogeを取ってきます。
問題はfunc3です。
やってることはfunc2と同じように見えます。しかしグローバルのhogeを取ってきています。
これの原因は関数を定義した場所にあります。
func1はfunc3の外側で定義されています。実は、この定義された瞬間にfunc1のスコープも決まってしまっています。
なので、func1を定義した場所から見るとfunc3のhogeはローカル変数になってしまい、その結果グローバルなhogeを取ってくることになったというわけです。
このように、関数を定義した時点でスコープが決まってしまうのが”レキシカルスコープ”です。
ブロックスコープとおんなじ感じで使ってしまうので要注意です。