學習JavaScript範圍的基礎知識
範圍是一組定義在編程語言中以確定變量值的規則。
JavaScript使用詞法範圍,這意味著變量的值由其在被寫入時的位置所定義,而不是在其被調用時,這是與另一種替代方式動態範圍不同的事情。
範圍是對程序的部分可見的變量集合。
我們有全局範圍,區塊範圍和函數範圍。如果一個變量在函數或區塊外部定義,它將附加到全局對象並具有全局範圍,這意味著它在程序的每個部分都可用。
var
,let
和const
聲明之間有一個非常重要的區別。
在函數內部定義為var
的變量只在該函數內部可見,就像函數參數一樣。
另一方面,在其所在的塊內定義為const
或let
的變量只在該塊內部可見。
重要的是要理解,塊(由一對花括號標識)不為var
定義新的範圍,但對於let
和const
則有。只有在創建函數時,才為var
創建新的範圍,因為var
沒有塊範圍,而是函數範圍。
在函數內部,任何在其中定義的var
變量在所有函數代碼中都可見,即使該變量在函數結束時聲明,它仍然可以在開頭引用,因為JavaScript在執行代碼之前實際上會將所有變量聲明移動到頂部(這被稱為提升)。為避免混淆,始終在函數開頭聲明var
變量。
這就是我的意思。即使你在函數結尾聲明了一個var
變量,它的聲明也會被移到頂部:
function run() {
console.log(`${name}`)
var name = 'Flavio'
}
run()
這將打印出“undefined”,因為實際上發生的是:
function run() {
var name;
console.log(`${name}`)
name = 'Flavio'
}
run()
let
和const
不會“受到”提升的影響。如果在上面的示例中使用它們之一,則會出現錯誤:ReferenceError: name is not defined
。
在JavaScript中,父函數的變量也可以在內部函數中使用。內部函數的範圍還包括父函數的範圍,這稱為閉包(我們將在後面更詳細地談論這一點)。
你需要注意一點。在非嚴格模式下,如果你使用未聲明的變量,無論你在哪裡使用,該變量都會附加到全局範圍。這可能是錯誤的根源。所以,在使用變量之前,請確保始終聲明變量。只是要意識到這一點,但這只是預設情況下使用嚴格模式的另一個原因,嚴格模式可以解決這個問題。我們之後再談論嚴格模式。
記住:在具有與全局變量同名的函數(或塊)中定義的任何變量優先於全局變量,遮蔽它。
這將打印undefined
:
var name = 'Roger'
function run() {
console.log(`${name}`)
var name = 'Flavio'
}
run()
而這將引發錯誤ReferenceError: name is not defined
:
let name = 'Roger'
function run() {
console.log(`${name}`)
let name = 'Flavio'
}
run()