做者:Lydia Halliejavascript
譯者:前端小智前端
來源:devjava
點贊再看,養成習慣git
本文
GitHub
github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。github
本篇咱們來看看啥是做用域以及做用域鏈,首先,來看看下面的代碼:面試
const name = "Lydia"
const age = 21
const city = "San Francisco"
function getPersonInfo() {
const name = "Sarah"
const age = 22
return `${name} is ${age} and lives in ${city}`
}
console.log(getPersonInfo())
// Sarah is 22 and lives in San Francisco
複製代碼
咱們調用getPersonInfo
函數,它返回一個包含姓名、年齡和城市變量值的字符串:Sarah is 22 and lives in San Francisco
。可是,getPersonInfo
函數中不包含變量 city
,它是怎麼取到 city
的值?瀏覽器
首先,JS 引擎爲不一樣的上下文設置內存空間。咱們有默認的全局上下文(瀏覽器中的window
、Node 中的global
),以及已經調用的getPersonInfo
函數的本地上下文,每一個上下文還有一個做用域鏈。函數
對於getPersonInfo
函數,做用域鏈看起來是這樣的:工具
做用域鏈基本上是對對象的「引用鏈」,其中包含對在執行上下文中可引用的值(和其餘做用域)的引用。做用域是在建立執行上下文時建立的,這說明它是在運行時建立的。學習
在本文中,不會討論激活對象或執行上下文,咱們只關注做用域。 在如下示例中,執行上下文中的鍵/值對錶示使做用域鏈對變量的引用。
**全局執行上下文(GLOBAL EXECUTION CONTEXT)的做用域鏈引用了3
個變量:值爲Lydia
的name
、值爲21
的age
和值爲San Francisco
的city
。在本地執行上下文(LOCAL EXECUTION CONTEXT)**中,咱們引用了兩個變量:name
值爲Sarah
, age
值爲22
。
當咱們試圖訪問getPersonInfo
函數中的變量時,JS引擎首先檢查局部做用域鏈。
本地做用域鏈有一個name
和age
的引用!name的值是Sarah, age的值是22。可是如今,當它試圖訪問city
變量時會發生什麼?
爲了找到變量city
的值,JS 引擎沿着做用域鏈向上查找,直到在外部做用域內爲找到了一個city
的值,本地做用域有一個引用,在本例中是全局對象。
在全局上下文中,咱們用San Francisco
的值聲明瞭變量city
,所以有一個對變量city
的引用。如今咱們有了變量的值,函數getPersonInfo
能夠返回字符串Sarah is 22 and lives in San Francisco
。
咱們能夠沿着做用域鏈向下走,可是咱們不能沿着做用鏈向上走,這可能會讓人困惑,由於咱們大都會說「向上」而不是「向下」,因此換一種說法:你能夠進入外部做用域,但不能進入內部做用域,能夠把它想象成瀑布模型:
更深的嵌套:
以這段代碼爲例:
這個跟上個例子代碼幾乎是同樣的,可是有一個很大的區別:咱們如今只在getPersonInfo
函數中聲明city
,而不在全局做用域中。這裏也沒有調用getPersonInfo
函數,因此也沒有建立本地上下文。然而,咱們試圖在全局上下文中訪問name
、age
和city
的值。
這裏分拋出一個ReferenceError
異常,由於 JS 在全局範圍內找不到一個名爲city
的變量的引用,由於已處於頂部做用域,也無法向上的做用域查找了。
經過這種方式,咱們能夠將做用域用做「保護」變量並從新使用變量名的方法。
除了全局做用域和局部做用域以外,還有一個塊做用域。使用let
或const
關鍵字聲明的變量的做用域就是塊做用域。
const age = 21
function checkAge() {
if (age < 21) {
const message = "You cannot drink!"
return message
} else {
const message = "You can drink!"
return message
}
}
複製代碼
能夠將上面的做用域可視化爲:
這裏有一個全局做用域、一個函數做用域和兩個塊做用域。咱們能夠兩次聲明變量message
,由於message 變量處在不一樣的做用域中。
快速回顧:
代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug。
交流
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。