在ES6以前,JavaScript沒有塊級做用域(一對花括號{}即爲一個塊級做用域),只有全局做用域和函數做用域。變量提高即將變量聲明提高到它所在做用域的最開始的部分函數
引擎會在解釋 JavaScript 代碼以前首先對其進行編譯(沒錯,JavaScript
也是要進行編譯的!),而編譯階段中的一部分工做就是找到全部聲明,並用合適的做用域將他們關聯起來,即
包括變量和函數在內的全部聲明都會在任何代碼被執行前首先被處理。
1.引擎在解析 JavaScript 代碼以前首先對其進行編譯。編譯階段中的一部分工做就是找到全部的聲明,並用合適的做用域將它們關聯起來;
2.變量和函數在內的全部聲明都會在任何代碼被執行前首先被處理;
3.當定義一個 var a = 1; 時,可能會認爲這是一個聲明。但 JavaScript 實際上會將其當作兩個聲明: var a; 和 a = 1; 。第一個定義聲明是在編譯階段進行。第二個賦值聲明會被留在原地等待執行階段。
**code
函數提高
**
解析器在解析時對函數聲明與函數表達式有着不一樣的優先級,實際上編譯階段函數聲明會先於變量被提高,並使其在執行任何代碼以前可訪問,函數表達式其實是變量聲明的一種,所以函數聲明提高優於函數表達式ip
函數聲明才存在函數提高內存
var num = 20; function test(){ console.log(num); // 20 num = 10; //去掉了var 就變成定義了全局變量了 console.log(num); // 10 } test(); console.log(num); // 10
外面的是全局的。裏面的能夠訪問它,裏面定義的在輸出後面,且不能變量提高。因此,就輸出外面的20了作用域
函數聲明和變量聲明都會被提高。可是函數會首先被提高,而後纔是變量。
局部變量 變量聲明提高io
var a= 20; function numa(){ console.log(a); // undefined var a= 10; //局部變量 console.log(a); // 10 } numa();
因爲函數體內存在變量聲明提高,因此上面代碼實際運行以下:console
var a = 20; function numa(){ var a; console.log(a); // undefined a = 10; console.log(a); // 10 } numa();