技術はあとからついてくる。

就活開始の半年前にエンジニアに目覚めた人

JavaScriptのスコープチェーンを理解する

勉強I/O

スコープチューンの理解に必要な2つのオブジェクトの理解から
GlobalオブジェクトとCallオブジェクト

Globalオブジェクト

グローバル変数やグローバル関数を扱うための便宜的なオブジェクト
関数配下に属さないトップレベルの変数や関数を意識せず利用できるようにしてくれる

var num = 10;
console.log(isNaN(num)); // isNaNはグローバル関数

スクリプトエンジンが初期化されるときに自動生成され、Globalオブジェクトが持つメンバが使用可能になる。

メンバ 概要
NaN 数値ではない
Infinity 無限大
undefined 未定義値
isFinite(val) 有限値であるかどうか
isNaN(val) 数値でないかどうか
String(val) 文字列型に変換する
Number(val) 数値型に変換する
Boolean(val) 真偽型に変換する
parseInt(val) 文字列を整数値に変換する
parseFloat(val) 文字列を浮動小数点値に変換する
escape(val) 文字列をエスケープする
unescape(val) エスケープされた文字列を戻す
encodeURIComponet(val) 文字列をURIエンコードする
decodeURIComponet(val) 文字列をURIデコードする
eval(val) 式や値を評価する

他のネイティブオブジェクトと違い、インスタンス化したり、メソッドを呼び出すことはできない

var global = new Global(); // インスタンス化はできない
Global.xxx(); // メソッド呼び出しもできない

Callオブジェクト とは

関数を呼び出すたびに内部的に生成されるオブジェクト
関数内のローカル変数を管理する
コーディングの際に意識することはない

スコープチェーンとは

JavaScriptがどんな順序で変数やプロパティを参照するか、を取り決めたルール

GlobalオブジェクトとCallオブジェクトを、生成した順に連結したリストのようなもの

このリストは、一番最初に生成されるGlobalオブジェクトを末端とし、Callオブジェクトが生成されるたびにその先端に紐づけているイメージ

JavaScriptの変数解決は
このリストの先頭から順に辿って、一番最初に見つかった値を採用する仕組みになっている。

sample.js

var x = 'Global';
var y = 'Global';

function outerFunc() {
  var x = 'Local Outer';
  function innerFunc() {
    var x = 'Local Inner';
    
    console.log(x); // Local Inner 
    console.log(y); // Global
    console.log(z); // undefined
  }
  console.log(x); // Local Outer
  innerFunc();
}
console.log(x); // Global
outerFunc();

実行結果

Global
Local Outer
Local Inner
Global
(undefined) // 本当はエラー

この時のスコープチェーン

先端
|innerFunc
|Callオブジェクト

|outerFunc
|Callオブジェクト

末端
|Globalオブジェクト

実行結果と照らし合わせてみると よりローカル(先端)な方から順に参照されていることがわかる。