探討Javascript的Hoisting

前言

Hoisting(中文翻作提升),這個概念在Javascript常常被使用到,特別在使用var和傳統function時就深深體會到Javascript特殊的地方,這一篇我們來簡單了解一下Hoisting的運作。


var變數的Hoisting

1
2
console.log(x) //印出undefined
var x = 10

上述結果會印出undefined,為什麼呢?因為這樣寫法等同於以下寫法

1
2
3
var x
console.log(x) //印出undefined
x = 10

可以看出Hoisting是指宣告的動作被提升

傳統函式的Hoisting

1
2
3
4
5
test()

function test() {
console.log("Hello") //印出Hello
}

上述結果會印出Hello,因為整個function都會被提升,這樣寫法等同於以下寫法

1
2
3
4
5
function test() {
console.log("Hello") //印出Hello
}

test()

這也就是為什麼在Javascript裡頭將一個函式用function宣告,也能順利執行函式的原因,因為整個function都提升到呼叫語句之前了阿!

var變數宣告函式的Hoisting

1
2
3
4
5
test()

var test = function() {
console.log("Hello")
}

會發生錯誤Uncaught TypeError: test is not a function” ,因為這樣的宣告方式等同於以下寫法

1
2
3
4
5
6
var test
test()

test = function() {
console.log("Hello")
}

可以看出Hoisting是指宣告的動作被提升,所以這邊的test是undefined,自然而然用函式的方式直接呼叫,瀏覽器就報給我們一個錯誤說test不是一個function。所以如果要用變數宣告function的話,務必要用以下的方式

1
2
3
4
5
var test = function() {
console.log("Hello")
}

test()

然後我也會習慣把var改為const方式來宣告,也有點防呆的機制,讓後續的指派變數動作不會誤指派值給這個function,因為我們也很少會把宣告出來的函式重新指派值

1
2
3
4
5
const test = function() {
console.log("Hello")
}

test()

小結

  1. Hoisting的宣告是指宣告的動作被提升,所以使用var來宣告變數或函式時要特別留意。
  2. 在實際專案中,我也較習慣宣告變數都使用let或是const,不會使用var,這樣就能避開Hoisting的問題;至於宣告函式我也習慣用const方式宣告,可以避免誤指派值的事情發生。