淺析JavaScript預編譯和暗示全域性變數
阿新 • • 發佈:2020-09-04
1. 暗示全域性變數
未宣告的變數稱為暗示全域性變數。
var a = 1; //函式體外宣告的變數稱為全域性變數 b = 2; // 無論函式體外或函式體內未宣告的變數都稱為暗示全域性變數 function fn() { var c = 3; //函式體內宣告的變數稱為區域性變數 d = 4; // 暗示全域性變數 } fn(); // 若不執行函式,則不會進行函式預編譯,d 就不會提升為全域性變數 console.log(c); // error: c is not defined console.log(d); // 4
2. JavaScript執行過程
1. 語法分析,若存在低階語法錯誤,則不編譯執行;
2. 預編譯,包括變數宣告提前和函式宣告提前;
3. 解釋執行,解釋一行,執行一行。
3. 預編譯
預編譯可分為全域性預編譯和函式預編譯。
預編譯可分為全域性預編譯和函式預編譯。
1. 在js指令碼載入之後,會先通篇檢查是否存在低階錯誤;
2. 在語法檢測完之後,便進行全域性預編譯;
3. 在全域性預編譯之後,就解釋一行,執行一行;
4. 當執行到函式呼叫那一行,會先進行函式預編譯,再往下執行。
全域性預編譯:
1. 建立全域性物件GO(window物件);
2. 變數宣告提前,將所有變數的宣告放到最前面,作為GO物件的屬性,
並賦值undefined,若存在變數名相同,只宣告一個;3. 函式宣告提前,將函式宣告也放到最前面,作為GO物件的屬性,
若函式名與變數名相同,變數名會被函式名覆蓋,值是函式體。
這就是函式定義放到函式呼叫之前或之後都可以的原因。
函式預編譯:
1. 在函式執行前的一瞬間,函式預編譯閃亮登場;
2. 先建立一個AO物件(Active Object);
3. 將形參和變數宣告提前,賦值undefined,作為AO的屬性;
4. 將實參賦值給形參;
5. 函式宣告提前,值為函式體,作為AO的屬性。
栗子:
var a = 1; function b(c){ console.log(c); var c = 2; console.log(c); function c() {} var d = 3; function e() {} } b(4);
先分析全域性預編譯,
- 建立GO物件,GO = {};
- 變數宣告提前
// 虛擬碼 GO = { a = undefined }
- 函式宣告提前
// 虛擬碼 GO = { a = undefined b = f b(c) { console.log(c); ... } }
再分析函式預編譯,
- 建立AO物件,AO = {};
- 形參和變數宣告提前;
// 虛擬碼 AO = { c = undefined // 與變數名相同,只宣告一個 d = undefined }
- 將實參賦值給形參;
// 虛擬碼 AO = { c = 4 // b(4),傳入的實參是4 d = undefined }
- 函式宣告提前
// 虛擬碼 AO = { c = f c() {} // 函式名會覆蓋變數名 d = undefined e = f e() {} }
所以第一次列印變數c的時候,是輸出函式體,而不是實參4。
以上就是淺析JavaScript預編譯和暗示全域性變數的詳細內容,更多關於JavaScript預編譯和暗示全域性變數的資料請關注我們其它相關文章!