P粉5462579132023-08-22 12:41:43
Javascript使用作用域鏈來決定給定函數的作用域。通常有一個全域作用域,每個定義的函數都有自己的巢狀作用域。在另一個函數內定義的任何函數都有一個與外部函數連結的局部作用域。它始終是原始程式碼中的位置定義作用域。
作用域鏈中的元素基本上是一個帶有指向其父作用域的指標的映射。
在解析變數時,javascript從最內層作用域開始向外搜尋。
P粉1655228862023-08-22 10:58:25
JavaScript具有詞法(也稱為靜態)作用域和閉包。這意味著你可以透過查看原始碼來確定標識符的作用域。
四種作用域如下:
除了全域和模組作用域的特殊情況外,變數使用var
(函數作用域)、let
(區塊作用域)和const
(區塊作用域)聲明。在嚴格模式下,大多數其他形式的識別碼聲明都具有區塊作用域。
作用域是程式碼庫中標識符有效的區域。
詞法環境是標識符名稱與與之關聯的值之間的對應。
作用域由詞法環境的連結嵌套形成,每個嵌套層級對應於祖先執行上下文的詞法環境。
這些連結的詞法環境形成了作用域「鏈」。標識符解析是沿著此鏈搜尋匹配標識符的過程。
標識符解析只會向外進行。這樣,外部詞法環境就無法「看見」內部詞法環境。
在決定JavaScript中識別符的作用域時,有三個相關因素:
一些標識符的宣告方式:
var
,let
和const
var
)import
語句eval
一些標識符的宣告位置:
使用var
聲明的標識符具有函數作用域,除非它們直接在全局上下文中聲明,此時它們將作為全局物件的屬性添加,並具有全局作用域。它們在eval
函數中的使用有單獨的規則。
使用let
和const
聲明的識別碼具有區塊作用域,除非它們直接在全域上下文中聲明,此時它們具有全域作用域。
注意:let
,const
和var
#都被提升。這意味著它們的邏輯定義位置是其封閉作用域(區塊或函數)的頂部。但是,使用let
和const
聲明的變數在控制流程通過原始程式碼的宣告點之前不能被讀取或賦值。這個臨時期稱為暫時死區。
function f() { function g() { console.log(x) } let x = 1 g() } f() // 1 because x is hoisted even though declared with `let`!