2.4 hoisting

在JavaScript程式語言當中,它會自動幫你把你有宣告的變數、Function自動拉至最上方

在 JavaScript 裡面,如果對一個還沒宣告的變數取值,會發生以下錯誤:

console.log(a)
// ReferenceError: a is not defined

會回傳a is not defined的錯誤,因為你還沒宣告這個變數,所以 JavaScript 也找不到這變數在哪,自然就會拋出錯誤。

可是如果你這樣子寫,神奇的事情發生了:

console.log(a) // undefined
var a

這種現象就叫做 hoisting,提升,在第二行的var a因為某種原因被「提升」到了最上面,所以上面的程式碼你可以「想像」成這樣:

var a
console.log(a) // undefined

再來還有一點要特別注意,那就是只有變數的宣告會提升,賦值不會,看看以下範例你就懂了:

console.log(a) // undefined
var a = 5

上面的程式碼你可以「想像」成這樣:

var a
console.log(a) // undefined
a = 5

函式運算式不會被提升

函式運算式(function expression)不會被提升。如下,foo 此時的值是 undefined,所以當執行 undefined() 就會得到 TypeError。而 bar 這個識別字是屬於 foo 的範疇的,所以在這裡會報錯 ReferenceError。

foo(); // TypeError
bar(); // ReferenceError

var foo = function bar() {
  // ...
};

重複宣告

若函式和變數同名,則函式會優先;若同時有多個函式同名,則後面的會覆寫前面的宣告。

範例 1:若函式和變數同名,則函式會優先

範例如下,同名函式 foo 和變數 foo,由於函式優先,因此 foo() 得到 1 而非 undefined() 的結果 TypeError。

foo(); // 1

var foo;

function foo() {
  console.log(1);
}

foo = 2;

範例 2:若同時有多個函式同名,則後面的會覆寫前面的宣告

範例如下,三個同名函式 foo,最後一個 foo 會覆寫前面的宣告,因此得到 3。

foo(); // 3

function foo() {
  console.log(1);
}

function foo() {
  console.log(2);
};

function foo() {
  console.log(3);
}

let、const 不會有hoisting

Last updated