現在讓我們了解3個關鍵字var、let、const,的特性和使用方法。
var
JavaScript中,我們通常說的作用域是函數作用域,使用var聲明的變量,無論是在代碼的哪個地方聲明的,都會提升到當前作用域的最頂部,這種行為叫做變量提升(Hoisting)
也就是說,如果在函數內部聲明的變量,都會被提升到該函數開頭,而在全局聲明的變量,就會提升到全局作用域的頂部。
function test() { console.log('1: ', a) //undefined if (false) { var a = 1 } console.log('3: ', a) //undefined } test()
實際執行時,上面的代碼中的變量a會提升到函數頂部聲明,即使if語句的條件是false,也一樣不影響a變量提升。
function test() {
var a
//a聲明沒有賦值
console.log('1: ', a) //undefined
if (false) {
a = 1
}
//a聲明沒有賦值
console.log('3: ', a) //undefined
}
在函數嵌套函數的場景下,變量只會提升到最近的一個函數頂部,而不會提升到外部函數。
//b提升到函數a頂部,但不會提升到函數test。
function test() {
function a() {
if (false) {
var b = 2
}
}
console.log('b: ', b)
}
test() //b is not defined
如果a沒有聲明,那么就會報錯,沒有聲明和聲明后沒有賦值是不一樣的,這點一定要區分開,有助於我們找bug
//a沒有聲明的情況
a is not defined
let
let和const都能夠聲明塊級作用域,用法和var是類似的,let的特點是不會變量提升,而是被鎖在當前塊中。
一個非常簡單的例子:
function test() {
if(true) {
console.log(a)//TDZ,俗稱臨時死區,用來描述變量不提升的現象
let a = 1
}
}
test() // a is not defined
function test() {
if(true) {
let a = 1
}
console.log(a)
}
test() // a is not defined
唯一正確的使用方法:先聲明,再訪問。
function test() {
if(true) {
let a = 1
console.log(a)
}
}
test() // 1
