1. 概念
當瀏覽器加載HTML頁面時,會先提供一個供全局JS代碼執行的環境(即全局作用域,window或者global),在這個環境中,瀏覽器默認會把所有帶var和function的變量進行提前聲明或者定義。
(1) 理解聲明和定義;
var num = 12; // 聲明: 告訴瀏覽器在全局作用域中有一個num變量 // 定義: 給變量進行賦值 // 使用隻聲明未定義的變量值為undefined;使用未聲明未定義的變量直接報錯
(2) 對於帶var和function關鍵字的變量在預解釋時的操作不一樣;
含var關鍵字的提前聲明,含function的提前聲明並且定義。
(3) 此時的預解釋隻發生在當前的全局作用域下,函數內部的變量不發生預解釋。執行函數時,函數內部的作用域同樣會發生預解釋。(關於函數執行時,內部發生的流程,見下一篇《JavaScript函數執行內部原理》)
2.預解釋機制的槽點
(1) 由於JavaScript沒有塊級作用域(es6有),在條件判斷語句中的var也會被預解釋,會帶來如下問題。
console.log(str); // undefined var str = "test1"; // 預解釋階段聲明全局變量str console.log(str2); // 報錯 str2 = "test2"; // 不會參與預解釋,隻相當於給window添加瞭屬性str2 console.log(fn1); // 1 function fn1(){ return 1; }
關於全局變量和window屬性的區別,點擊這裡。
例2:
console.log(total); // undefined var total = 0; function fn(num1,num2) { console.log(total); // undefined var total = num1 + num2; console.log(total); // 300 } fn(100,200); console.log(total); // 0