1. 程式人生 > 程式設計 >淺析JavaScript預編譯和暗示全域性變數

淺析JavaScript預編譯和暗示全域性變數

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預編譯和暗示全域性變數的資料請關注我們其它相關文章!