Variable Hosting 變量提高

爲何要講變量提高,首先看一個小測試,若是你答錯了,那就說明你須要瞭解一下變量提高的機制javascript

0 測試

看看下面分別輸出多少?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

 

1 變量提高

只有變量聲明如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 :(';

 

2 函數提高

函數提高有點不一樣,有兩種定義函數的方式:函數表達式和函數聲明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 :(");
}

 

3 示例

變量提高前的代碼

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

相關文章
相關標籤/搜索