[譯]JavaScript️可視化:做用域鏈

本系列

正文

如今開始講做用域鏈🕺🏼在這篇文章中,我假設您瞭解執行上下文:儘管如此,我也將很快就此發表一篇文章😃javascript

讓咱們看下面的代碼:java

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())

複製代碼

咱們調用getPersonInfo函數,該函數返回一個包含name,age,city的值的字符串: Sarah is 22 and lives in San Francisco。可是getPersonInfo函數不包含名爲city🤨 的變量。它怎麼知道city的?git

首先,爲不一樣的上下文設置存儲空間。咱們有默認的全局上下文(在瀏覽器中是window,在Node中是 global),以及getPersonInfo的局部上下文。每一個上下文也都有一個做用域鏈github

對於getPersonInfo來講,做用域鏈看起來像這樣(看不懂?不用擔憂,下面會講):瀏覽器

做用域鏈是對對象的「引用鏈」,這些對象包含對在該執行上下文中可引用的值(和其餘做用域)。(⛓:「嘿,這些都是您能夠在此上下文中引用的全部值」。)做用域鏈是在建立執行上下文時建立的,這意味着它是在運行時建立的!函數

可是,在本文中,我通常不會討論活動對象或執行上下文,咱們只關注做用域!在如下示例中,執行上下文中的鍵/值對錶示做用域鏈對變量的引用。oop

全局執行上下文的做用域鏈引用了3個變量:name的值是Lydia,age的值是21,city的值是San Francisco。在本地上下文中,咱們引用了2個變量:name的值是Sarah和age的值是22。post

當咱們嘗試訪問getPersonInfo函數中的變量時,引擎首先檢查本地做用域鏈。ui

本地做用域鏈引用了name和age!name的值爲Sarah,age的值爲22。可是如今,當它嘗試訪問city時會發生什麼?spa

爲了找到city的值,引擎「沿做用域鏈往下」。這意味着引擎不會輕易放棄:它會努力爲您查看是否能夠city在本地做用域引用的外部做用域(在本例中爲全局對象)中找到變量的值。

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


咱們能夠順着做用域鏈向下,但咱們順着做用域鏈向上。(好吧,這可能會使人困惑,由於有些人說的是向上而不是向下,因此我要改寫:您可使用外部做用域,但不能進入內部做用域。我想用瀑布形象地表示這一點

甚至更深:

讓咱們以這段代碼爲例。

幾乎同樣,可是有一個很大的不一樣:咱們如今僅在getPersonInfo函數中聲明city,而不是在全局範圍中聲明。咱們沒有調用getPersonInfo函數,所以也沒有建立本地上下文。然而,咱們試圖在全局做用域訪問name,age,city。

它拋出ReferenceError!在全局做用域內它找不到一個叫作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用大括號括起來,所以咱們可以對變量進行兩次聲明。


快速回顧:

  • 您能夠將「做用域鏈」視爲對咱們能夠在當前上下文中訪問的值的引用鏈。
  • 做用域可讓咱們重複使用外部做用域裏的變量

範圍(鏈)就是這樣!關於這一點,還有不少話要說,因此我會在空閒時間添加一些額外的信息。若是您遇到任何困難,請隨時提出問題,我很樂意提供幫助!💕

原文

本系列包括6篇文章

我的博客

github.com/abc-club/fr…

相關文章
相關標籤/搜索