本文講解Javascript變量提高引發的問題以及如何規避。javascript
今天看到一道有意思的面試題,考察的還真是JS的基本功,題目以下:java
var name = "world"; (function(){ if(typeof name === "undefined") { var name = "Jack"; console.log("Hello " + name); } else { console.log("Hello " + name); } }());
根據if條件能夠得出可能的答案:面試
答案是Hello Jack
,可是答案怎麼來的,回答很差可能仍是隻能打50分,有如下兩種理解:瀏覽器
理解1:函數
當即執行函數有獨立的做用域,訪問不到外部name,因此if判斷成立,輸出
Hello Jack
這個理解是不正確的。雖然函數隔離了做用域,可是因爲做用域鏈的關係,JS會從當前做用域一直往上級查找,直到頂級做用域(瀏覽器環境爲window)。code
以下代碼輸出Hello world
ip
var name = "world"; (function(){ console.log("Hello " + name); }());
理解2:內存
var存在變量提高,因此if在判斷的時候name確實爲undefined,走了if分支,輸出
Hello Jack
MDN對變量提高的解釋:作用域
「變量提高」意味着變量和函數的聲明會在物理層面移動到代碼的最前面,但這麼說並不許確。實際上變量和函數聲明在代碼裏的位置是不會動的,而是在編譯階段被放入內存中。get
敲黑板: JavaScript 僅提高聲明,而不提高初始化
- 函數和變量相比,會被優先提高
根據變量提高理論咱們能夠「模擬」JS實際執行代碼的過程:
var name = "world"; (function(){ var name; // 變量提高,僅提高聲明,不提高初始化 if(typeof name === "undefined") { name = "Jack"; console.log("Hello " + name); } else { console.log("Hello " + name); } }());
函數內部做用域頂級的name初始化時爲undefined,因此會走if分支,輸出Hello Jack
。這纔是100分答案!
- 在做用域的頂部定義變量
- 使用ES6新語法let或const定義變量