# Version A - Function Declaration Statement
// Some JavaScript code
function a() {
// code within function
}
//Some more JavaScript code
# Version B - Function Expression
// Some JavaScript code
var b = function () {
// code within function
};
// Some more JavaScript code
私は JavaScript: The Definitive Guide を読んでいて、これら 2 つのバージョンが JavaScript によってどのように処理されているかを理解したいと思っていました。以下の各バージョンについて、私の理解を説明します。
バージョン A
- JavaScript はグローバル スコープでスクリプトをスキャンし、すべての変数と関数の定義を識別して、それらを一番上に上げます。変数の割り当てと関数の評価はまだ行われません。
- 関数 a() の場合、JavaScript はグローバル コンテキストをパッケージ化し、それを関数のスコープ チェーンに関連付けます。この時点で、関数 a() はステップ 1 のすべての変数と関数の定義を認識します。
- JavaScript は関数 a() を評価しないため、関数内のローカル コンテキストについては何も知りません。これは、関数が呼び出されるまで true のままです。
バージョン B
上記のステップ 1 と同じ - JavaScript はグローバル スコープでスクリプトをスキャンし、すべての変数と関数の定義を識別して、それらを一番上に持ち上げます。変数 b が一番上に持ち上げられているため、スクリプトは次のようになります。
var b; // Some JavaScript code b = function (){ /* code within function */ }; // Some more JavaScript code
JavaScript が変数 b の割り当てに到達すると、無名関数オブジェクトが定義されていることがわかります。JavaScript が関数を定義すると、関数が定義されているコンテキスト (この場合はグローバル コンテキスト) がパッケージ化され、関数のスコープ チェーンに関連付けられます。この時点で、無名関数は、未定義の var b を含むステップ 1 のすべての変数と関数の定義を認識します。
- JavaScript は、関数が変数割り当ての式として使用されていることを認識するため、関数式を評価します。関数式を評価するとき、ローカル スコープ内のすべての変数と関数の定義を再び一番上に持ち上げます。この関数式内に関数宣言ステートメントがある場合は、このローカル コンテキストをパッケージ化し、スコープ チェーンに追加します。この機能の。
- 関数が評価されると関数オブジェクトが返され、その関数オブジェクトが var b に割り当てられます。
各バージョンについてコメントして、私の理解が正確かどうか教えていただければ幸いです。