JS的作用域和作用域鏈

 

作用域

定義

作用域是指在程序中定義變量的區域,該位置決定了變量的生命週期。通俗地理解,作用域就是變量與函數的可訪問範圍,即作用域控制着變量和函數的可見性和生命週期。

⚠️:作用域是由代碼中函數聲明的位置來決定的,跟在哪裏調用無關

用途

作用域最大的用處就是隔離變量,不同作用域下同名變量不會有衝突。

類別

  • 全局作用域
  1. 最外層函數 和在最外層函數外面定義的變量擁有全局作用域
  2. 所有末定義直接賦值的變量自動聲明爲擁有全局作用域
  3. 所有 window 對象的屬性擁有全局作用域
  • 函數作用域

在函數內部定義的變量或者函數,並且定義的變量或者函數只能在函數內部被訪問。函數執行結束之後,函數內部定義的變量會被銷燬。

  • 塊級作用域(ES6新增)

ES6 引入了 let 和 const 關鍵字,從而使 JavaScript 也能像其他語言一樣擁有了塊級作用域。

作用域鏈

定義

簡單來說就是由作用域組成的鏈條。例如在函數裏面有個a變量,函數內部不存在,則會找他的父級作用域,直到找到或者在全局作用域還沒找到則放棄。(在ES5之後是通過變量環境裏的outer即外部環境來實現的)

用途

通過作用域來找變量(查找變量的機制)。注意⚠️:內部環境可以通過作用域鏈訪問所有外部環境,但外部環境不能訪問內部環境的任何變量和函數。

作用域與執行上下文

許多開發人員經常混淆作用域和執行上下文的概念,誤認爲它們是相同的概念,但事實並非如此。

我們知道 JavaScript 屬於解釋型語言,JavaScript 的執行分爲:解釋和執行兩個階段,這兩個階段所做的事並不一樣。

解釋階段

  • 詞法分析
  • 語法分析
  • 作用域規則確定

執行階段

  • 創建執行上下文
  • 執行函數代碼
  • 垃圾回收

JavaScript 解釋階段便會確定作用域規則,因此作用域在函數定義時就已經確定了,而不是在函數調用時確定,但是執行上下文是函數執行之前創建的。執行上下文最明顯的就是 this 的指向是執行時確定的。而作用域訪問的變量是編寫代碼的結構確定的。

其實大家看下作用域和執行上下文各自的職責,你會發現他們幾乎是沒有啥交集的。那麼爲啥通常兩者會被同時提到呢?因爲在一個函數被執行時,創建的執行上下文對象除了保存了些代碼執行的信息,還會把當前的作用域保存在執行上下文中。所以它們的關係只是存儲關係。

參考

https://www.cnblogs.com/fundebug/p/10535230.html

極客時間瀏覽器原理與實踐

https://www.jianshu.com/p/cc79f22b99fe

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章