国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript內部原理系列-執行上下文(Execution Context)

imingyu / 2473人閱讀

摘要:一系列活動的執行上下文從邏輯上形成一個棧。棧底總是全局上下文,棧頂是當前活動的執行上下文。同樣的,當拋出未捕獲的異常時,也會退出一個或者多個執行上下文,也會做相應的退棧操作。

概要

本文將向大家介紹ECMAScript的執行上下文以及相關的可執行代碼類型。

定義

每當控制器到達ECMAScript可執行代碼的時候,控制器就進入了一個執行上下文。
執行上下文(簡稱:EC)是個抽象的概念,ECMA-262標準中用它來區分不同類型的可執行代碼。

標準中并沒有從技術實現的角度來定義執行上下文的具體結構和類型;這是實現標準的ECMAScript引擎所要考慮的問題。

一系列活動的執行上下文從邏輯上形成一個棧。棧底總是全局上下文,棧頂是當前(活動的)執行上下文。當在不同的執行上下文間切換(退出的而進入新的執行上下文)的時候,棧會被修改(通過壓棧或者退棧的形式)。

可執行代碼類型

可執行代碼類型和執行上下文相關。有的時候,當提到代碼類型的時候,其實就是在說執行上下文。

舉個例子,我們將執行上下文的棧以數組的形式來表示:

ECStask = [ ];

每次控制器進入一個函數(哪怕該函數被遞歸調用或者作為構造器),都會發生壓棧的操作。內置eval函數工作的時候也不例外。

全局代碼

這類代碼是在“程序”級別上被處理的:比如,加載一個外部的js文件或者內聯的js代碼(被包含在標簽內)。全局代碼不包含任何函數體內的代碼。

在初始化的時候(程序開始),ECStack如下所示:

ECStack = [
    globalContext
];
函數代碼

一旦控制器進入函數代碼(各類函數),就會有新的元素會被壓棧到ECStack。要注意的是:實體函數代碼并不包括內部函數的代碼。如下所示,我們調用一個函數,該函數遞歸調用自己一次:

(function foo(bar){
    if (bar){

    return;

}

foo(true);
})();

之后,ECStack就被修改成如下所示:

//首先激活foo函數
ECStack = [
     functionContext
    globalContext
];
//遞歸激活foo函數
ECStack = [
     functionContext - recursively
     functionContext
    globalContext
];

每次函數返回,退出當前活動的執行上下文時,ECStack就會被執行對應的退棧操作——先進后出——和傳統的棧實現一致。同樣的,當拋出未捕獲的異常時,也會退出一個或者多個執行上下文,ECStack也會做相應的退棧操作。待這些代碼完成之后,ECStack中就只剩下一個執行上下文(globalContext)——直到整個程序結束。

Eval代碼

說到eval代碼就比較有意思了。這里要提到一個叫做調用上下文的概念,比如:調用eval函數時候的上下文,就是一個調用上下文,eval函數中執行的動作(例如:變量聲明或者函數聲明)會影響整個調用上下文:

eval(‘var x = 10’);
(function foo(){
    eval(‘ var y = 20’);
})();
alert(x); // 10
alert(y); // ”y” is not defined

ECStack會被修改為:

ECStack = [
    globalContext
];
//eval(‘var x = 10’);
ECStack.push(
    evalContext,
    callingContext: globalContext
);

// eval exited context
ECStack.pop();

//foo function call
ECStack.push( functionContext);

//eval(‘ var y = 20’);
ECStack.push(
    evalContext,
    callingContext:  functionContext
);

//return from eval
ECStack.pop();

//return from foo
ECStack.pop();

在1.7以上版本SpiderMonkey的實現中(Firefox,Thunderbird瀏覽器內置的JS引擎),允許在調用eval函數的時候,將調用上下文作為第二個參數傳遞給eval函數。因此,如果傳入的調用上下文存在的話,就有可能會影響該上下文中原有的私有變量(在該上下文中聲明的變量):

function foo(){
    var x = 1;
    return function() { alert(x); }
};

var bar = foo();

bar(); // 1
eval(‘x = 2’, bar); //傳遞上下文,影響了內部變量“var x”
bar(); // 2
總結

這些基本理論對于后面執行上下文相關的細節(諸如變量對象、作用域鏈等等)分析是非常必要的。

擴展閱讀

ECMA-363-3標準文檔的對應的章節—— 10. 執行上下文

via 前端翻譯小站
趙靜(goddyzhao)譯自 Dmitry A.Soshnikov的文章Execution Context

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/85448.html

相關文章

  • js運行機制及異步編程(一)

    摘要:引擎的運行原理引擎也是程序,是屬于瀏覽器的一部分,由瀏覽器廠商自行開發。為了提高運行速度,現代瀏覽器一般采用即時編譯即字節碼只在運行時編譯,用到哪一行就編譯哪一行,并且把編譯結果緩存這樣整個程序的運行速度能得到顯著提升。 相信大家在面試的過程中經常遇到查看執行順序的問題,如setTimeout,promise,async await等等,各種組合,是不是感覺頭都要暈掉了,其實這些問題最...

    happen 評論0 收藏0
  • js運行機制及異步編程(一)

    摘要:引擎的運行原理引擎也是程序,是屬于瀏覽器的一部分,由瀏覽器廠商自行開發。為了提高運行速度,現代瀏覽器一般采用即時編譯即字節碼只在運行時編譯,用到哪一行就編譯哪一行,并且把編譯結果緩存這樣整個程序的運行速度能得到顯著提升。 相信大家在面試的過程中經常遇到查看執行順序的問題,如setTimeout,promise,async await等等,各種組合,是不是感覺頭都要暈掉了,其實這些問題最...

    wudengzan 評論0 收藏0
  • JavaScript基礎系列---執行環境與作用域鏈

    摘要:延長作用域鏈下面兩種語句可以在作用域鏈的前端臨時增加一個變量對象以延長作用域鏈, 問題 今天看筆記發現自己之前記了一個關于同名標識符優先級的內容,具體是下面這樣的: 形參優先級高于當前函數名,低于內部函數名 形參優先級高于arguments 形參優先級高于只聲明卻未賦值的局部變量,但是低于聲明且賦值的局部變量 函數和變量都會聲明提升,函數名和變量名同名時,函數名的優先級要高。執行代...

    J4ck_Chan 評論0 收藏0
  • javascript系列--javascript引擎執行的過程的理解--語法分析和預編譯階段

    摘要:所以覺得把這個執行的詳細過程整理一下,幫助更好的理解。類似的語法報錯的如下圖所示三預編譯階段代碼塊通過語法分析階段之后,語法都正確的下回進入預編譯階段。另開出新文章詳細分析,主要介紹執行階段中的同步任務執行和異步任務執行機制事件循環。 一、概述 js是一種非常靈活的語言,理解js引擎的執行過程對于我們學習js是非常有必要的??戳撕芏噙@方便文章,大多數是講的是事件循環(event loo...

    malakashi 評論0 收藏0
  • 理解JavaScript的核心知識點:This

    摘要:關鍵字計算為當前執行上下文的屬性的值。毫無疑問它將指向了這個前置的對象。構造函數也是同理。嚴格模式無論調用位置,只取顯式給定的上下文綁定的,通過方法傳入的第一參數,否則是。其實并不屬于特殊規則,是由于各種事件監聽定義方式本身造成的。 this 是 JavaScript 中非常重要且使用最廣的一個關鍵字,它的值指向了一個對象的引用。這個引用的結果非常容易引起開發者的誤判,所以必須對這個關...

    TerryCai 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<