JavaScript引擎的工做方式是,先解析代碼,獲取全部被聲明的變量,而後再一行一行地運行。這形成的結果,就是全部的變量的聲明語句,都會被提高到代碼的頭部,這就叫作變量提高。函數
示例:code
console.log(a) // undefined var a = 1 function b() { console.log(a) } b() // 1
上面的代碼實際執行順序是這樣的:ip
第一步 引擎將var a = 1拆解爲var a = undefined和 a = 1,並將var a = undefined放到最頂端,a = 1還在原來的位置;作用域
var a = undefined console.log(a) // undefined a = 1 function b() { console.log(a) } b() // 1
第二步 就是執行,所以js引擎一行一行從上往下執行就形成了當前的結果,這就叫變量提高。io
當前做用域內的聲明都會提高到做用域的最前面,包括變量和函數的聲明console
(function(){ var a = "1"; var f = function(){}; var b = "2"; var c = "3"; })();
變量a,f,b,c的聲明會被提高到函數做用域的最前面,相似以下:function
(function(){ var a,f,b,c; a = "1"; f = function(){}; b = "2"; c = "3"; })();
請注意函數表達式並無被提高,這也是函數表達式與函數聲明的區別。進一步看兩者的區別:變量
(function(){ //var f1,function f2(){}; //hoisting,被隱式提高的聲明 f1(); //ReferenceError: f1 is not defined f2(); var f1 = function(){}; function f2(){} })();
上面代碼中函數聲明f2被提高,因此在前面調用f2是沒問題的。雖然變量f1也被提高,但f1提高後的值爲undefined,其真正的初始值是在執行到函數表達式處被賦予的。因此只有聲明是被提高的。co