【動畫演示】:JS 做用域鏈不在話下

做者: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個變量:值爲Lydianame、值爲21age和值爲San Franciscocity。在本地執行上下文(LOCAL EXECUTION CONTEXT)**中,咱們引用了兩個變量:name值爲Sarah, age值爲22

當咱們試圖訪問getPersonInfo函數中的變量時,JS引擎首先檢查局部做用域鏈。

本地做用域鏈有一個nameage的引用!name的值是Sarah, age的值是22。可是如今,當它試圖訪問city變量時會發生什麼?

爲了找到變量city的值,JS 引擎沿着做用域鏈向上查找,直到在外部做用域內爲找到了一個city的值,本地做用域有一個引用,在本例中是全局對象

在全局上下文中,咱們用San Francisco的值聲明瞭變量city,所以有一個對變量city的引用。如今咱們有了變量的值,函數getPersonInfo能夠返回字符串Sarah is 22 and lives in San Francisco

咱們能夠沿着做用域鏈向下走,可是咱們不能沿着做用鏈向上走,這可能會讓人困惑,由於咱們大都會說「向上」而不是「向下」,因此換一種說法:你能夠進入外部做用域,但不能進入內部做用域,能夠把它想象成瀑布模型:

更深的嵌套:

以這段代碼爲例:

這個跟上個例子代碼幾乎是同樣的,可是有一個很大的區別:咱們如今只在getPersonInfo函數中聲明city,而不在全局做用域中。這裏也沒有調用getPersonInfo函數,因此也沒有建立本地上下文。然而,咱們試圖在全局上下文中訪問nameagecity的值。

這裏分拋出一個ReferenceError異常,由於 JS 在全局範圍內找不到一個名爲city的變量的引用,由於已處於頂部做用域,也無法向上的做用域查找了。

經過這種方式,咱們能夠將做用域用做「保護」變量並從新使用變量名的方法。

除了全局做用域和局部做用域以外,還有一個塊做用域。使用letconst關鍵字聲明的變量的做用域就是塊做用域。

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 變量處在不一樣的做用域中。

快速回顧:

  • 能夠將「做用域鏈」看做是在當前上下文中訪問的值的引用鏈。
  • 做用域還能夠重用在該該做用域鏈上定義的變量名,由於它會沿着做用域鏈向上查找。

原文:dev.to/lydiahallie…

代碼部署後可能存在的BUG無法實時知道,過後爲了解決這些BUG,花了大量的時間進行log 調試,這邊順便給你們推薦一個好用的BUG監控工具 Fundebug


交流

乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。

github.com/qq449245884…

我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!

關注公衆號,後臺回覆福利,便可看到福利,你懂的。

相關文章
相關標籤/搜索