Line 1:Global Scope,沒有 function 或 var,不做事。 Line 2:Global Scope,有 var,我想宣告一個非函式變數 a,先去 Global LE 找找看有沒有一樣的變數。 沒有就產生新的 identifier,賦予 undefined;有找到一樣的變數,就不做事。
Line 1:Global Scope,我要執行 RHS 查找,去 Global LE 裡面找找有沒有變數 a, 結果在第 11 行找到,輸出 a 的值 - undefined。 Line 2:Global Scope,我要執行 LHS 查找去 Global LE 裡面找找有沒有變數 a, 結果在第 11 行找到,賦予 a 新的值 - 1。
functionfn2(){ var x = 2; y = 99; functionfn1(){ console.log(x); // 輸出結果:2 } console.log(y); // 輸出結果:99 fn1(); }
fn2();
一開始會直接先產生一個 Global EC,跟上述一樣,為了節省篇幅就不重複寫出來。接著編譯器從第一行程式碼開始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Line 1:Global Scope,有 var,想宣告一個非函式變數 x,先去 Global LE 找找看有沒有一樣的變數。 沒有找到,於是產生新的 identifier,賦予 undefined。 Line 2:Global Scope,有 var,想宣告一個非函式變數 y,先去 Global LE 找找看有沒有一樣的變數。 沒有找到,於是產生新的 identifier,賦予 undefined。 Line 3:沒事。 Line 4:Global Scope,有 function,想宣告一個函式變數 fn2,先去 Global LE 找找看有沒有一樣的變數。 沒有找到,於是產生新的 identifier,賦予指向函式物件的 reference。 並且開始產生「fn2 執行環境資料」。 Line 5:fn2 Scope,有 var,想宣告一個非函式變數 x,先去 fn2 LE 找找看有沒有一樣的變數。 沒有找到,於是產生新的 identifier,賦予 undefined。 Line 6:沒事。 Line 7:fn2 Scope,有 function,想宣告一個函式變數 fn1,先去 fn2 LE 找找看有沒有一樣的變數。 沒有找到,於是產生新的 identifier,賦予指向函式物件的 reference。 並且開始產生「fn1 執行環境資料」。 Line 8-15:沒事。
functionfn2(){ var x = 2; y = 99; functionfn1(){ console.log(x); // 輸出結果:2 } console.log(y); // 輸出結果:99 fn1(); }
fn2();
JavaScript 引擎從第一行程式碼開始執行:
1 2 3 4 5 6 7
Line 1:Global Scope,我要執行 LHS 查找,去 Global LE 裡面找找有沒有變數 x, 結果在第 11 行找到,賦予 x 新的值 - 1。 Line 2:Global Scope,我要執行 LHS 查找去 Global LE 裡面找找有沒有變數 y, 結果在第 12 行找到,賦予 y 新的值 - 10。 Line 15:Global Scope,我要執行 RHS 查找,去 Global LE 裡面找找有沒有變數 fn2, 結果在第 13 行找到,並且發現它真的是函式物件,於是成功呼叫。 並且將「fn2 執行環境資料 (fn2 EC)」複製一份,放入 stack 中。
functionfn2(){ var x = 2; y = 99; functionfn1(){ console.log(x); // 輸出結果:2 } console.log(y); // 輸出結果:99 fn1(); }
fn2();
開始執行 fn2:
1 2 3 4
Line 5:fn2 Scope,我要執行 LHS 查找,去 fn2 LE 裡面找找有沒有變數 x, 結果在 fn2 LE 第 8 行找到,賦予 x 新的值 - 2。 Line 6:fn2 Scope,我要執行 LHS 查找,去 fn2 LE 裡面找找有沒有變數 y,沒有找到, 去上層 Global LE 找,結果找到了,賦予 Global LE 中的 y 新的值 - 99。