專欄剛剛開通, 先把本身之前寫的一些沒人看的答案搬運過來填補一下空白.函數
變量的問題,莫過於聲明和賦值兩個步驟,而這兩個步驟是分開的。code
函數聲明被提高時,聲明和賦值兩個步驟都會被提高,對象
而普通變量卻只能提高聲明步驟,而不能提高賦值步驟。io
變量被提高事後,先對提高上來的全部對象統一執行一遍聲明步驟,function
而後再對變量執行一次賦值步驟。變量
而執行賦值步驟時,會優先執行函數變量的賦值步驟,再執行普通變量的賦值步驟。專欄
當你明白這三點後,一切都豁然開朗了。co
首先來看一個DEMO:
(function(){ function a(){}; var a; alert(typeof a); //function })();
先提高兩個a,而後執行函數的賦值步驟,a沒有被賦值,故結果爲function
再看一個:
(function(){ alert(typeof a);//function function a(){}; var a = 1; })();
先提高兩個a,再執行函數的賦值步驟,
由於在alert語句執行之前,還未執行a = 1的賦值步驟,函數不會被覆蓋,故爲function
來個最有說服力的:
(function(){ var a = 1; function a(){}; alert(typeof a); //number })();
在alert語句執行以前,a = 1步驟和函數賦值步驟均已執行,
並且函數還在a = 1賦值語句以後,可是仍然輸出number,
就是由於函數的賦值步驟會先於a = 1的賦值步驟,函數被覆蓋,故輸出number。