爲何要講變量提高,首先看一個小測試,若是你答錯了,那就說明你須要瞭解一下變量提高的機制javascript
看看下面分別輸出多少?java
console.log(x); // -> ? var x = 5; console.log(x); // -> ? console.log(y); // -> ?
答案是:ide
第二個log爲5,能夠理解,第一個undefined也能夠理解,爲何最後的y是error呢?函數
由於Javascript engine 在運行代碼前,會從新調整代碼的結構,提高了變量x的聲明,上面的代碼在運行前結構大致變成了這樣測試
var x; console.log(x); // -> undefined x = 5; console.log(x); // -> 5 console.log(y); // -> Uncaught ReferenceError: y is not defined
只有變量聲明如var = x會被提高的代碼的頂部,變量的賦值如var x = 10不會被提高;ui
沒有使用變量聲明關鍵字如var,let, const等的變量聲明也不會被提高spa
console.log(x); console.log(y); var x = 'This will log "undefined"!'; y = 'This will throw an error :(';
函數提高有點不一樣,有兩種定義函數的方式:函數表達式和函數聲明code
函數表達式: 相似變量提高,fn被提高到代碼頂部,而且值爲undefined,以後fn被賦值函數ip
var fn = function() { // do something... }
函數聲明: 整個代碼塊都會被提高,變量fn就是函數自己,會被提高到最頂部,甚至在變量聲明以前get
function fn() { // do something... }
示例:
fnDeclaration(); // -> This works! fnExpression(); // -> Uncaught TypeError: fnExpression is not a function function fnDeclaration() { console.log('This works!'); } var fnExpression = function() { console.log("This won't work :("); }
變量提高前的代碼
var a = 123; var b = 'abc'; var fnExpression = function() { var c = 456; var d = 'def'; } function fnDeclaration() { var e = 789; }
變量提高後的代碼
function fnDeclaration() { var e; e = 789; } var a; var b; var fnExpression; a = 123; b = 'abc'; fnExpression = function() { var c; var d; c = 456; d = 'def'; }
先聲明老是對的,函數提高有點意思,函數表達式和變量聲明很像,函數聲明才最靠前
參考資料:《Step Up Your JS: A Comprehensive Guide to Intermediate JavaScript》