摘要:例如在上面的代碼中,執行語句時,作用域鏈的最頂端是臨時添加的對象,因此可以直接訪問對象的屬性獲取值。在執行語句時,會創建一個新的變量對象該對象中包含被拋出的錯誤對象,并添加到作用域鏈的頂端。
執行環境(也就是常說的上下文)和作用域是js中很基礎也很重要的概念, 但在很多時候,特別是看其他的文檔的時候,卻容易混淆概念,這篇文章試著梳理下執行環境和作用域的概念。
1、執行環境
執行環境定義了變量或函數有權訪問的其他數據,決定了它們各自的行為。每個執行環境都有一個相關聯的變量對象,這個對象里面保存了環境中定義的所有變量和函數。這個變量對象在編寫代碼是不能訪問的(除了最外層的window對象),只有解析器在后臺處理才能使用。
執行環境可以分成兩種:全局執行環境和函數執行環境。在執行js代碼之前,默認都會創建一個全局的執行環境,與之關聯的是window對象,里面保存了所有全局變量和函數,直到頁面關閉時才銷毀。而當執行某個函數時,會創建一個活動對象,并把這個對象作為與該函數的執行環境關聯的變量對象,從而創建出函數的執行環境。函數的執行環境在函數執行完之后,就會被銷毀。
另外,需要提一句的是:在活動對象剛被創建時,對象中只有arguments對象一個屬性。
2、作用域
了解執行環境,就可以來說作用域了。
在js中,執行環境是用環境棧來管理的。最底層的是全局執行環境,當執行到一個函數, 函數的執行環境就會被推入到環境棧中。如果在函數中繼續執行函數,那么內部函數的執行環境就繼續被推入環境棧。例如下面的代碼:
var name = "window"; outer(); function outer(){ var name = "outer"; inner(); //函數內部的函數 function inner(){ var name = "inner"; console.log(name); } }
對應的環境棧如下:
環境棧中的變量對象,從上到下就組成一條作用域鏈, 用來保證對執行環境有權訪問的所有變量和函數的有序訪問。解析標識符時,就沿著作用域鏈一級一級地搜索,也就在環境棧中從上向下一個個對象搜索,直到找到標識符,就返回,否則就報錯。例如,上面的代碼,執行后會輸出‘inner’,當把inner函數中的定義變量語句注釋之后就輸出‘outer’。
2、延長作用域鏈
在兩種情況下,雖然不是在執行函數,但也會在作用域鏈的前端臨時增加一個變量對象:
try-catch語句的catch塊
with 語句
在執行with 語句時,會將指定的對象添加到作用域鏈中。例如:
function getHost() { var res = ""; with(location){ res = host; } return res; }
在上面的代碼中,執行with語句時,作用域鏈的最頂端是臨時添加的location對象,因此可以直接訪問location對象的host屬性獲取值。
在執行catch語句時,會創建一個新的變量對象(該對象中包含被拋出的錯誤對象),并添加到作用域鏈的頂端。正因為這個原因,在js的編程中,如果不是必要的,不建議在代碼中使用try-catch語句塊。
備注:
在第一個例子中,我們把inner函數定義在outer函數的內部,如果是定義在outer函數外部呢?會不會有什么不同?原因是什么?
寫在最后:
如果覺得我寫的文章對你有幫助,歡迎掃碼關注我的公眾號:海痕筆記
微信號:haihenbiji
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82221.html
摘要:所以,全局執行環境的變量對象始終都是作用域鏈中的最后一個對象。講到這里,可能你已經對執行環境執行環境對象變量對象作用域作用域鏈的理解已經他們之間的關系有了一個較清晰的認識。 JavaScript中的執行環境、作用域、作用域鏈、閉包一直是一個非常有意思的話題,很多博主和大神都分享過相關的文章。這些知識點不僅比較抽象,不易理解,更重要的是與這些知識點相關的問題在面試中高頻出現。之前我也看過...
摘要:當執行流進入一個函數時,函數的環境就會被推入一個環境棧中。在函數執行完后,棧將其環境彈出,把控制權返回給之前的執行環境。執行環境可以分為創建執行銷毀三個階段。在這個階段,作用域鏈會被初始化,的值也會被最終確定。 執行環境 執行環境中定義了變量和函數有權訪問的其他數據,決定了他們各自的行為。 當JavaScript解釋器初始化執行代碼時,它首先默認進入全局執行環境,從此刻開始,函數的每...
摘要:作用域與作用域鏈每個函數都有自己的執行環境。這是初步了解作用域,如想更深入了解作用域,請看下面鏈接作用域原理作用域鏈由一道題圖解的作用域或者看權威指南和高級程序設計 本文是我學習JavaScript作用域整理的筆記,如有不對,請多指出。 作用域 一個變量的作用域是程序源代碼中定義這個變量的區域。 而在ES5中只分為全局作用域和函數作用域,也就是說for,if,while等語句是不會創建...
摘要:全局執行環境的變量對象始終是作用域鏈中的最后一個變量對象。綜上,每個函數對應一個執行環境,每個執行環境對應一個變量對象,而多個變量對象構成了作用域鏈,如果當前執行環境是函數,那么其活動對象在作用域鏈的前端。 1.幾個概念 先說幾個概念:函數、執行環境、變量對象、作用域鏈、活動對象。這幾個東東之間有什么關系呢,往下看~ 函數 函數大家都知道,我想說的是,js中,在函數內部有兩個特殊...
摘要:執行上下文環境然后將執行上下文環境壓棧,設置為活動狀態當前唯一然后執行到第行,調用函數。有閉包存在時,一個作用域存在兩個上下文環境也是有的。這就是作用域鏈。 本文參考引自:深入理解javascript原型和閉包(完結)不得不說,這個系列文章是真的給人恍然頓悟的感覺,寫的非常好,強烈推薦。感謝大佬! 執行上下文 函數每調用一次,都會產生一個新的執行上下文環境。因為不同的調用可能就有不同的...
摘要:講作用域鏈首先要從作用域講起,下面是百度百科里對作用域的定義作用域在許多程序設計語言中非常重要。原文出處談談語法里一些難點問題二 3) 作用域鏈相關的問題 作用域鏈是javascript語言里非常紅的概念,很多學習和使用javascript語言的程序員都知道作用域鏈是理解javascript里很重要的一些概念的關鍵,這些概念包括this指針,閉包等等,它非常紅的另一個重要原因就...
閱讀 3579·2021-11-04 16:06
閱讀 3573·2021-09-09 11:56
閱讀 842·2021-09-01 11:39
閱讀 893·2019-08-29 15:28
閱讀 2289·2019-08-29 15:18
閱讀 823·2019-08-29 13:26
閱讀 3327·2019-08-29 13:22
閱讀 1039·2019-08-29 12:18