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オブジェクト
実行結果と照らし合わせてみると よりローカル(先端)な方から順に参照されていることがわかる。