摘要:正文執(zhí)行環(huán)境的理解執(zhí)行環(huán)境或者執(zhí)行上下文后面簡稱定義了變量或者函數有權訪問的其他數據,決定了他們各自的行為。最后全局環(huán)境的變量對象總結活動對象和變量對象是執(zhí)行環(huán)境在不同生命期的不同叫法。未進入執(zhí)行階段之前,變量對象中的屬性都不能訪問。
背景
夯實基礎才是進步的根源,基礎不牢地動山搖!!于是乎,結合《javascript高級程序設計》來點基礎的學習和理解。本文主要會有兩部分。rt!!
正文1、執(zhí)行環(huán)境的理解
執(zhí)行環(huán)境(或者執(zhí)行上下文)(execution context 后面簡稱ec)定義了變量或者函數有權訪問的其他數據,決定了他們各自的行為。如果不好理解的話,接著看后面。
全局執(zhí)行環(huán)境是最外圍的一個執(zhí)行環(huán)境,在web瀏覽器中,全局執(zhí)行環(huán)境被默認為是指window對象。因此所有的全局變量和函數都是作為window對象的屬性和方法創(chuàng)建的。全局執(zhí)行環(huán)境直到應用程序推出才會被銷毀(例如關閉網頁或者瀏覽器的時候)。
每個函數都有自己的執(zhí)行環(huán)境。當執(zhí)行流進入一個函數的時候,函數的環(huán)境就會被推入一個環(huán)境棧中,而在函數執(zhí)行之后,棧將其環(huán)境彈出。把控制權返回給之前的執(zhí)行環(huán)境了。
執(zhí)行環(huán)境一般分為全局執(zhí)行環(huán)境和函數執(zhí)行環(huán)境。
這個時候應該上代碼了(高程上的代碼)
var color = "blue"; function changeColor() { var anotherColor = "red"; function swapColors() { var tempColor = anotherColor; anotherColor = color; color = tempColor; } swapColors(); } changeColor();
來看看流程吧:
全局環(huán)境入棧
全局環(huán)境入棧之后,其中的可執(zhí)行代碼開始執(zhí)行,直到遇到了changeColor(),這一句激活函數changeColor創(chuàng)建它自己的執(zhí)行上下文,因此第二步就是changeColor的執(zhí)行上下文入棧。
changeColor的環(huán)境入棧之后,js執(zhí)行引擎開始執(zhí)行其中的可執(zhí)行代碼,遇到swapColors()之后又激活了一個執(zhí)行上下文。因此第三步是swapColors的執(zhí)行上下文入棧。
在swapColors的可執(zhí)行代碼中,再沒有遇到其他能生成執(zhí)行環(huán)境的情況,所以在swapColors順利執(zhí)行完畢后,swapColors的環(huán)境從棧中彈出
swapColors環(huán)境彈出后繼續(xù)changeColor的執(zhí)行,發(fā)現沒有可以執(zhí)行的了。然后就彈出。
最后只剩下全局環(huán)境了。這個是要只有關閉當前網頁或者瀏覽器就能銷毀該環(huán)境。
總結
所有變量都存在于一個執(zhí)行環(huán)境中。
全局環(huán)境只能訪問全局環(huán)境中的變量和函數,不能訪問局部環(huán)境中的任何數據。
執(zhí)行環(huán)境有全局執(zhí)行環(huán)境和函數執(zhí)行環(huán)境之分。
js單線程,是同步執(zhí)行的,只有棧頂的環(huán)境處于執(zhí)行中,其他環(huán)境需要等待。
2、變量對象的理解
上面我們講到了執(zhí)行環(huán)境,環(huán)境中的變量和函數都是保存在什么地方的呢?
好了,不賣關子了。每個執(zhí)行環(huán)境都有一個與該環(huán)境相關聯(lián)的變量對象(variable object)。環(huán)境中定義的所有變量和函數都是保存在這個對象中的。雖然我們編寫的代碼沒有辦法直接訪問這個對象,但是js解析器在處理數據的時候會使用它。
執(zhí)行環(huán)境的生命周期:
變量對象的創(chuàng)建
上面就是變量對象的一個創(chuàng)建過程,這個過程的解釋:
建立arguments對象。檢查當前上下文中的參數,建立該對象下的屬性與屬性值。
檢查當前上下文的函數聲明,也就是使用function關鍵字聲明的函數。在變量對象中以函數名建立一個屬性,屬性值為指向該函數所在內存地址的引用。如果函數名的屬性已經存在,那么該屬性將會被新的引用所覆蓋。
檢查當前上下文中的變量聲明,每找到一個變量聲明,就在變量對象中以變量名建立一個屬性,屬性值為undefined。如果該變量名的屬性已經存在,為了防止同名的函數被修改為undefined,則會直接跳過,原屬性值不會被修改。
上面的代碼解釋:
function test(c, d) { console.log(d); console.log(a); console.log(bar()); console.log(c); var a = 1; function bar() { return 2; } } test(3,4); //創(chuàng)建過程 EC = execution context testEC = { // 變量對象 VO: {}, // 作用于鏈 scopeChain: {}, // 確定this指向 this: {} } // VO = Variable Object,即變量對象 VO = { arguments: { c: undefined, d: undefined }, //注:在瀏覽器的展示中,函數的參數可能并不是放在arguments對象中,這里為了方便理解,我做了這樣的處理 bar:// 表示foo的地址引用 a: undefined } // 執(zhí)行階段 VO -> AO // Active Object AO = { arguments: { c: 3, d: 4 }, bar: , a: 1 } // 實際執(zhí)行 function test(c, d) { // arguments = { c : 3, d : 4 }; // 這樣理解方便點,理解arguments對象 function foo() { return 2; } var a; console.log(a); console.log(foo()); a = 1; } test(3, 4);
就是在執(zhí)行環(huán)境在創(chuàng)建階段的時候所有的變量是不能被訪問的,只有在執(zhí)行階段的時候才能被訪問,因為此時的變量對象被轉換成了活動對象。
// 執(zhí)行階段 VO -> AO // Active Object AO = { arguments: {...}, foo:, a: 1 }
說到底變量對象和活動對象本質上是一樣的,只是處于執(zhí)行環(huán)境的不同生命期。
最后全局環(huán)境的變量對象
windowEC = { VO: window, scopeChain: {}, this: window }
總結:
活動對象和變量對象是執(zhí)行環(huán)境在不同生命期的不同叫法。
function聲明會比var聲明優(yōu)先級更高一點。
未進入執(zhí)行階段之前,變量對象中的屬性都不能訪問。
感謝《javascript高級程序設計》
知乎上面的答案
波同學變量對象詳解
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82789.html
摘要:所以,全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個對象。講到這里,可能你已經對執(zhí)行環(huán)境執(zhí)行環(huán)境對象變量對象作用域作用域鏈的理解已經他們之間的關系有了一個較清晰的認識。 JavaScript中的執(zhí)行環(huán)境、作用域、作用域鏈、閉包一直是一個非常有意思的話題,很多博主和大神都分享過相關的文章。這些知識點不僅比較抽象,不易理解,更重要的是與這些知識點相關的問題在面試中高頻出現。之前我也看過...
摘要:所以覺得把這個執(zhí)行的詳細過程整理一下,幫助更好的理解。類似的語法報錯的如下圖所示三預編譯階段代碼塊通過語法分析階段之后,語法都正確的下回進入預編譯階段。另開出新文章詳細分析,主要介紹執(zhí)行階段中的同步任務執(zhí)行和異步任務執(zhí)行機制事件循環(huán)。 一、概述 js是一種非常靈活的語言,理解js引擎的執(zhí)行過程對于我們學習js是非常有必要的。看了很多這方便文章,大多數是講的是事件循環(huán)(event loo...
摘要:所以覺得把這個執(zhí)行的詳細過程整理一下,幫助更好的理解。類似的語法報錯的如下圖所示三預編譯階段代碼塊通過語法分析階段之后,語法都正確的下回進入預編譯階段。另開出新文章詳細分析,主要介紹執(zhí)行階段中的同步任務執(zhí)行和異步任務執(zhí)行機制事件循環(huán)。 一、概述 js是一種非常靈活的語言,理解js引擎的執(zhí)行過程對于我們學習js是非常有必要的。看了很多這方便文章,大多數是講的是事件循環(huán)(event loo...
摘要:至此作用域鏈創(chuàng)建完畢。好了,通過深入理解作用域鏈,我們能跟好的理解的運行機制和閉包的原理。 前言 理解javascript中的作用域和作用域鏈對我們理解js這們語言。這次想深入的聊下關于js執(zhí)行的內部機制,主要討論下,作用域,作用域鏈,閉包的概念。為了更好的理解這些東西,我模擬了當一個函數執(zhí)行時,js引擎做了哪些事情--那些我們看不見的動作。 關鍵詞: 執(zhí)行環(huán)境 作用域 作用域鏈 變...
摘要:作用域鏈的用途,是保證對執(zhí)行環(huán)境有權訪問的所有變量和函數的有序訪問。這樣,一直延續(xù)到全局執(zhí)行環(huán)境全局執(zhí)行環(huán)境的變量對象始終都是作用域鏈中的最后一個對象。標識符解析是沿著作用域鏈一級一級地搜索標識符的過程。 執(zhí)行環(huán)境(execution context,為簡單起見,有時也成為環(huán)境)是javascript中最為重要的一個概念。執(zhí)行環(huán)境定義了變量或函數有權訪問的其他數據,決定了它們各自...
閱讀 1558·2021-09-22 15:52
閱讀 3469·2021-09-22 14:59
閱讀 2848·2021-09-02 15:12
閱讀 977·2021-08-20 09:35
閱讀 1581·2019-08-30 14:09
閱讀 2714·2019-08-30 13:56
閱讀 1652·2019-08-26 18:27
閱讀 3367·2019-08-26 13:37