摘要:不同執行上下文中的變量對象對于所有的執行上下文類型,變量對象的一些操作比如變量實例化和行為是共通的。從這點看,將變量對象看作是抽象的基礎的東西很便利。全局上下文的變量對象現在,應該先給出全局對象的定義。
原文地址
作者的話有很多文章已經對ECMAScript的核心概念做了詳盡解讀。本系列文章翻譯自Dmitry Soshnikov的個人網站,相信不少人已經看過原文或者譯文。原文簡潔易懂并且嚴謹,條理清晰地闡明了所有JavaScript開發者不得不深入理解的ECMAScript核心概念。重復翻譯的原因主要是為了個人收藏、整理之用。初次翻譯,技巧拙劣,如有不足,請不吝賜教。
正文介紹
數據聲明
不同執行上下文中的變量對象
全局上下文中的變量對象
函數上下文中的變量對象
處理上下文代碼的階段
進入執行上下文
代碼執行
關于變量
實現的特點:__parent__屬性
結論
介紹我們總是在程序中聲明函數和變量,然后成功地用作構建我們的系統。但是,解釋器怎樣以及在哪里找到我們的數據(函數和變量)?當我們引用需要的對象的時候發生了什么?
許多ECMAScript開發者知道變量和執行上下文緊密相關。
var a = 10; // variable of the global context (function () { var b = 20; // local variable of the function context })(); alert(a); // 10 alert(b); // "b" is not defined
同時,許多程序員也知道當前版本(ES6之前,譯者注)的標準的獨立作用域是通過“函數”代碼類型的執行上下文創建的。比如,和C/C++相反,ECMAScript中的for循環塊不會創建本地上下文。
for (var k in {a: 1, b: 2}) { alert(k); } alert(k); // variable "k" still in scope even the loop is finished
讓我們看看當我們聲明數據時的所發生的細節。
數據聲明如果變量和執行上下文相關,那么應該知道變量的數據存在哪里以及如何獲取它們。這個機制被稱為變量對象
變量對象(簡稱:VO)是一個與執行上下文相關的特殊對象,它存儲了在上下文中聲明的:
變量
函數聲明
函數形參
注意,在ES5中,變量對象的概念已經被詞法環境模式取代,可以在適當的章節找到它的詳細描述。
示意性的舉個例子,可以將變量對象表示成一個普通的ECMAScript對象:
VO = {};
正如我們所說,VO是執行上下文的屬性:
activeExecutionContext = { VO: { // context data (var, FD, function arguments) } };
只允許在全局上下文(全局對象就是變量對象的地方)中,對變量間接引用(通過VO的屬性名)。對于其他上下文,對VO對象的直接引用是不可能的,這純粹是實現機制。
當我們聲明了一個變量或函數,除了使用我們的變量的名字和值創建VO的新屬性,沒別的了。
比如:
var a = 10; function test(x) { var b = 20; }; test(30);
相應的變量對象是這樣:
// Variable object of the global context VO(globalContext) = { a: 10, test:}; // Variable object of the "test" function context VO(test functionContext) = { x: 30, b: 20 };
但是在實現層面(以及規范)中,變量對象是一個抽象的概念。物理上,在具體的執行上下文中,VO被叫做不同的名稱,有不同的初始結構。
不同執行上下文中的變量對象對于所有的執行上下文類型,變量對象的一些操作(比如變量實例化)和行為是共通的。從這點看,將變量對象看作是抽象的基礎的東西很便利。函數上下文也可以定義與變量對象相關的額外內容。
AbstractVO (generic behavior of the variable instantiation process) ║ ╠══> GlobalContextVO ║ (VO === this === global) ║ ╚══> FunctionContextVO (VO === AO,object and are added)
我們詳細解讀一下。
全局上下文的變量對象現在,應該先給出全局對象的定義。
全局對象是在進入任何執行上下文前創建的對象;這個對象僅存在一份,它的屬性可以在程序的任何位置訪問到,全局對象的生命周期伴隨著程序結束而結束。
在創建時,全局對象使用諸如:Math、String、Date、parseInt等初始化,也可以使用附加對象初始化,附加對象可以是全局對象本身的引用--比如在BOM中,全局對象的window屬性引用全局對象(不是在所有的實現中都是如此)。
global = { Math: <...>, String: <...> ... ... window: global };
當引用全局對象的屬性,前綴往往可以省略,因為全局對象不能通過名字直接訪問到。然而,在全局上下文中可以通過this值訪問到它,也可以通過對它的遞歸引用訪問到它,比如BOM中的window,因此可以簡寫:
String(10); // means global.String(10); // with prefixes window.a = 10; // === global.window.a = 10 === global.a = 10; this.b = 20; // global.b = 20;
所以回到全局上下文的變量對象,這里變量對象就是全局對象本身:
VO(globalContext) === global;
很有必要理解這個事實,由于這個原因,在全局上下文中聲明一個變量,我們可以通過全局對象的屬性間接訪問它(比如,當變量名事先未知時):
var a = new String("test"); alert(a); // directly, is found in VO(globalContext): "test" alert(window["a"]); // indirectly via global === VO(globalContext): "test" alert(a === this.a); // true var aKey = "a"; alert(window[aKey]); // indirectly, with dynamic property name: "test"函數上下文的變量對象
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96863.html
摘要:邏輯上講,活躍的執行上下文集合組成了一個棧。棧底是全局上下文,棧頂是當前活躍執行上下文。舉個例子,我們將執行上下文定義成一個數組。一個拋出但是沒有捕獲的異常可能導致退出一個或多個執行上下文代碼代碼更加復雜。 原文地址 作者的話 有很多文章已經對ECMAScript的核心概念做了詳盡解讀。本系列文章翻譯自Dmitry Soshnikov的個人網站,相信不少人已經看過原文或者譯文。原文簡潔...
摘要:如果在全局代碼中調用函數,程序的順序流進入被調用的函數,創建新的執行上下文并將其推送到執行堆棧的頂部。每次調用函數時,都會創建一個新的執行上下文。 翻譯:瘋狂的技術宅鏈接:http://davidshariff.com/blog/... 本文首發微信公眾號:jingchengyideng歡迎關注,每天都給你推送新鮮的前端技術文章 在這篇文章中,我將深入探討JavaScript的最...
摘要:堆棧結構的底部是全局執行上下文,頂部是當前執行上下文。不同的執行上下文切換時堆棧會發生改變譯論及代碼類型時,在某些時候可能也意味著執行上下文。函數體中代碼執行完后,只剩全局上下文直到程序結束譯代碼更有意思。 第一次翻譯,希望各位多多包涵,有錯誤處還望指出,歡迎提出建議。 Chapter 1.Execution Contexts Introduction (介紹) Definitio...
摘要:前言大家學的時候,經常遇到自執行匿名函數的代碼,今天我們主要就來想想說一下自執行。其實,前面兩個例子里的變量,也可以換成,因為和外面的不在一個作用于,所以不會出現問題,這也是匿名函數閉包的威力。 前言 大家學JavaScript的時候,經常遇到自執行匿名函數的代碼,今天我們主要就來想想說一下自執行。 在詳細了解這個之前,我們來談了解一下自執行這個叫法,本文對這個功能的叫法也不一定完全對...
摘要:然后最后一步就是從父作用域鏈中將該特殊對象刪除,整個過程的偽代碼如下注意這里,該屬性不能刪除,只讀。 起因是我在逛sf的時候看到了一個人的提問: 為什么將函數c賦值給變量b,在函數體里面,給c賦值,為什么會失敗?也就是這代碼執行時為什么c打印出來的不是3 var b = function c () { a=1, b=2, c=3; console.log(a); ...
閱讀 3530·2021-11-23 10:10
閱讀 3292·2019-08-30 14:03
閱讀 2066·2019-08-30 13:09
閱讀 3392·2019-08-29 15:29
閱讀 1540·2019-08-29 11:23
閱讀 2002·2019-08-28 18:28
閱讀 2840·2019-08-26 13:34
閱讀 2168·2019-08-26 11:32