本篇內容主要講解“什么是作用域與作用域鏈”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“什么是作用域與作用域鏈”吧!
如果說執行上下文是代碼的執行環境,那么作用域就是執行環境中的一套執行規則,既然是規則,JavaScript 引擎執行代碼時要遵守這套規則,同時開發人員在寫代碼時,同樣也要遵守這套規則。
我們先來看這樣一個例子:
function foo () { var bar = 'xiaolu' } foo() console.log(bar)
上述的運行結果很明顯,控制臺會報錯 bar is not defined,我們可以通過這個小例子就可以發現在函數外部訪問函數內部聲明的變量是不可訪問的,這背后的原因就是 JavaScript 作用域存在導致的結果。
2. 什么是詞法環境
說到作用域,那什么是作用域?我們先來認識一下這位老朋友詞法環境。
ECMAScript 規范中對詞法環境的描述如下:詞法環境是用來定義基于詞法嵌套結構的 ECMAScript 代碼內的標識符與變量值和函數值之間的關聯關系的一種規范類型。 |
說的直白一點,詞法環境就是一套規范和規則,它用來規定某些函數和變量的可訪問范圍等,我們也稱詞法環境為「詞法作用域」。
既然詞法作用域是一套約定好的規則,那么詞法作用域的作用范圍是開發人員在寫代碼的時候就已經是確定了的。
當代碼執行的時候, JavaScript 引擎就會根據這套規范通過標識符名稱來查找相對應的變量和函數。
好吧,最后給它做個總結性的定義。
作用域:作用域是一套約定好的規范和規則,它用來規定某些函數和變量的可訪問性等。 |
2. 作用域鏈
作用域我們弄明白了,我們再來看作用域鏈。作用域鏈和作用域卻大不相同,咱們分別從「執行棧層面」和「代碼層面」來體驗一下什么是作用域鏈。
var name = "xiaolu"; function fn () { console.log(name); function getName(){ console.log(name); } getName(); } fn();
執行棧中的作用域鏈示意圖:
該示意圖為上述代碼的執行情況,在上述示意圖中,不同的色塊縮進形成的可訪問鏈就是我們所說的作用域鏈。
雖然上述示意圖是抽象出來的,如果我們在代碼層面來理解作用域鏈,又是如何實現的呢?
在上一篇中分享到,每當創建一個新的執行上下文時,都會創建一個「變量對象」用于存放當前執行上下文中的變量和函數。(記?。哼@個變量對象很重要)
如果我們把這些執行上下文的「變量對象」關聯起來,就形成了一條鏈,我們把這條鏈的實現稱為「作用域鏈」。
上述代碼的執行結果是打印輸出:
var name = "xiaolu"; function fn () { console.log(name); function getName(){ console.log(name); } getName(); } fn();
當內部的 getName 執行時 JavaScript 引擎就在 getName 作用域內查找變量 name,發現并沒有,就會沿著上圖中的作用域鏈往上層尋找,在 fn 的作用域中也沒有發現 name 變量,然后繼續沿著作用域鏈往上層的尋找,直到全局作用域中,發現存在變量 name,然后輸出 name 的值。
到此,相信大家對“什么是作用域與作用域鏈”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。