摘要:如果是嵌套的作用域的話,這些嵌套作用域會通過作用域鏈把嵌套作用域聯系在一起。全局沒有則報錯但是上級作用域沒法通過作用域鏈訪問下級作用域。通過作用域鏈能讓引擎對執行環境里所有有權訪問的變量和函數進行有序訪問。
一 為什么要有作用域
我們知道,變量對于程序來說是至關重要的,如果沒有變量存儲和訪問值,整個程序會受到限制。那么問題來了,既然程序這么需要變量,那么它到底是怎么樣去存儲變量和使用變量的呢?存儲變量這里暫且不提,到時候會有專門一篇博客來說明這個問題。我們這次說的主要就是如何去使用變量。這就要牽扯到我們今天的主題作用域上面了。
概括的來說,作用域就是一套能讓你有序訪問變量的規則。(注意有序很重要)javascript中只有函數能封閉作用域(let函數也能綁定一個塊級作用域,這里先不做討論).
來看下面一個例子
function foo (a) { var b = a * 2 function bar (c) { console.log(a, b, c) } bar(b * 3) console.log(c) } foo(2)
(1)foo函數內部會形成一個作用域
(2)bar函數內部會形成一個作用域
(3)有一個全局的作用域
我們前面說過,作用域是一套能讓你有序訪問變量的規則,那么上述代碼運行的時候,作用域是怎么樣訪問變量的呢?來看看下面的示意圖。
,一個是函數bar的作用域,一個是函數foo的作用域,一個是全局的作用域。并且這三個作用域是嵌套的。
(1)bar作用域中有一個變量c
(2)foo作用域中有三個變量a,b,bar
(3)全局作用域中有一個變量foo
我們來看看上面代碼的運行過程,首先執行最外層的foo(2),foo在調用棧調用bar,bar執行。但是注意bar內部的執行語句為
console.log(a,b,c)
我們前面已經說過,bar作用域中只有變量c,那么上述語句是否會出現錯誤呢,答案是不會。上述代碼會正常輸出。那么為什么會這樣呢?答案就是代碼在運行的過程中有一個作用域鏈能作用域給串起來。如下圖
內部的作用域可以訪問外部作用域的變量。所以bar函數在執行console.log(a,b,c)時,在當前作用域中如果沒有找到a,b變量,它會順著作用域鏈往上找,在上層作用域foo中找到了a,b變量,它就會使用上層作用域a,b的值。如果上層作用域還是沒有a,b的話,它會順著作用域繼續查找,直到全局變量。如果全局變量仍然沒有,程序就會報錯。那么既然內部作用域能沿著作用域鏈訪問到外部作用域,那么外部作用域能不能順著作用域鏈訪問內部作用域呢?不急,繼續看下面代碼。
執行完bar函數后,bar函數從執行棧中彈出,繼續執行foo函數剩余的語句,console.log(c)
由于當前作用域中不存在變量c,但是其子作用域內有變量c的定義,那么程序會不會輸出子級作用域的變量c呢?答案是不會。
上級作用域不能通過作用鏈進入下級作用域。只有下級作用域能通過作用鏈進入上級作用域。只就是作用域的有序性。有序的訪問所有能訪問的變量和函數。
作用域就像一個一個封閉的空間,不同作用域內的變量是不會相互影響的。但是作用域之間又會有聯系。如果是嵌套的作用域的話,這些嵌套作用域會通過作用域鏈把嵌套作用域聯系在一起。內部作用域能通過作用域鏈訪問到上級作用域的變量。即如果當前作用域中沒有某個變量,引擎會通過作用域鏈查找上級作用域看看有沒有定義該變量。直到全局作用域。(全局沒有則報錯)
但是上級作用域沒法通過作用域鏈訪問下級作用域。這就是作用域的有序性。通過作用域鏈能讓引擎對執行環境里所有有權訪問的變量和函數進行有序訪問。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84441.html
摘要:講作用域鏈首先要從作用域講起,下面是百度百科里對作用域的定義作用域在許多程序設計語言中非常重要。原文出處談談語法里一些難點問題二 3) 作用域鏈相關的問題 作用域鏈是javascript語言里非常紅的概念,很多學習和使用javascript語言的程序員都知道作用域鏈是理解javascript里很重要的一些概念的關鍵,這些概念包括this指針,閉包等等,它非常紅的另一個重要原因就...
摘要:作用域鏈的用途,是保證對執行環境有權訪問的所有變量和函數的有序訪問。這樣,一直延續到全局執行環境全局執行環境的變量對象始終都是作用域鏈中的最后一個對象。標識符解析是沿著作用域鏈一級一級地搜索標識符的過程。 執行環境(execution context,為簡單起見,有時也成為環境)是javascript中最為重要的一個概念。執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自...
摘要:目錄執行環境與作用域鏈立即執行函數閉包知識點什么是閉包使用閉包的意義與注意點閉包的具體應用小結這是基本語法的函數部分的第篇文章,主要講述了中比較重要的知識點閉包在講閉包之前,在上一篇函數二的基礎上,進一步深化執行環境和作用域鏈的知識點,并補 目錄 1.執行環境與作用域鏈 2. 立即執行函數 3. 閉包知識點 3.1 什么是閉包 3.2 使用閉包的意義與注意點 3.3 閉包的具體應用 4...
摘要:執行環境又稱作執行上下文,其作用就是規定了對環境內的變量還有函數的操作權利,主要分為全局的執行環境和局部的執行環境。創建作用域鏈的作用主要是讓每個嵌套關聯的執行環境中的變量和函數有序的調用和操作。 1 執行環境(exeution context)又稱作執行上下文,其作用就是規定了對環境內的變量還有函數的操作權利,主要分為全局的執行環境和局部的執行環境。 2 當一段代碼進行運行的時候...
摘要:正式由于作用域鏈的這種關系,我們就不難理解,為什么和不能通過作用域鏈向上搜索,因為對和的搜索在當前執行函數的活動對象就停止了。 對于Javascript程序員來說,閉包總會讓你覺得既熟悉又陌生,然而它對于開發人員來說卻非常重要,javascript里的許多設計模式中都用到了閉包,此處以函數作用域為例。 //示例代碼 var a=1; function foo(){ ...
閱讀 1868·2021-11-22 09:34
閱讀 1141·2021-10-09 09:44
閱讀 3001·2021-09-29 09:35
閱讀 3617·2021-09-14 18:01
閱讀 1465·2021-08-16 10:49
閱讀 1084·2019-08-29 14:11
閱讀 849·2019-08-29 12:47
閱讀 3068·2019-08-26 13:47