考慮如下代碼: a = 2; var a; console.log( a ); 你認爲console.log(..) 聲明會輸出什麼呢?
----->2java
考慮另一段代碼: console.log( a ); var a = 2; 鑑於上一個代碼片斷所表現出來的某種非自上而下的行爲特色,你可能會認爲這個代碼片 段也會有一樣的行爲而輸出2。還有人可能會認爲,因爲變量a 在使用前沒有先進行聲明, 所以會拋出ReferenceError 異常。 不幸的是兩種猜想都是不對的。輸出來的會是undefined。
解析:
函數
引擎會code
在解釋JavaScript 代碼以前首先對其進行編譯(雖然js是動態語言,可是js引擎仍是會編譯js代碼);ip
編譯階段中的一部分工做就是找到全部的聲明,並用合適的做用域將它們關聯起來作用域
咱們的第二個代碼片斷實際是按照如下流程處理的: var a; console.log( a ); a = 2;
所以,打個比方,這個過程就好像變量和函數聲明從它們在代碼中出現的位置被「移動」console
到了最上面。這個過程就叫做提高。編譯
函數聲明和變量聲明都會被提高。可是一個值得注意的細節(這個細節能夠出如今有多個class
「重複」聲明的代碼中)是函數會首先被提高,而後纔是變量。變量