成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript內(nèi)部原理系列-執(zhí)行上下文(Execution Context)

imingyu / 2475人閱讀

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

概要

本文將向大家介紹ECMAScript的執(zhí)行上下文以及相關(guān)的可執(zhí)行代碼類型。

定義

每當(dāng)控制器到達(dá)ECMAScript可執(zhí)行代碼的時候,控制器就進(jìn)入了一個執(zhí)行上下文。
執(zhí)行上下文(簡稱:EC)是個抽象的概念,ECMA-262標(biāo)準(zhǔn)中用它來區(qū)分不同類型的可執(zhí)行代碼。

標(biāo)準(zhǔn)中并沒有從技術(shù)實現(xiàn)的角度來定義執(zhí)行上下文的具體結(jié)構(gòu)和類型;這是實現(xiàn)標(biāo)準(zhǔn)的ECMAScript引擎所要考慮的問題。

一系列活動的執(zhí)行上下文從邏輯上形成一個棧。棧底總是全局上下文,棧頂是當(dāng)前(活動的)執(zhí)行上下文。當(dāng)在不同的執(zhí)行上下文間切換(退出的而進(jìn)入新的執(zhí)行上下文)的時候,棧會被修改(通過壓?;蛘咄藯5男问剑?。

可執(zhí)行代碼類型

可執(zhí)行代碼類型和執(zhí)行上下文相關(guān)。有的時候,當(dāng)提到代碼類型的時候,其實就是在說執(zhí)行上下文。

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

ECStask = [ ];

每次控制器進(jìn)入一個函數(shù)(哪怕該函數(shù)被遞歸調(diào)用或者作為構(gòu)造器),都會發(fā)生壓棧的操作。內(nèi)置eval函數(shù)工作的時候也不例外。

全局代碼

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

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

ECStack = [
    globalContext
];
函數(shù)代碼

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

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

    return;

}

foo(true);
})();

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

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

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

Eval代碼

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

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的實現(xiàn)中(Firefox,Thunderbird瀏覽器內(nèi)置的JS引擎),允許在調(diào)用eval函數(shù)的時候,將調(diào)用上下文作為第二個參數(shù)傳遞給eval函數(shù)。因此,如果傳入的調(diào)用上下文存在的話,就有可能會影響該上下文中原有的私有變量(在該上下文中聲明的變量):

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

var bar = foo();

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

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

擴(kuò)展閱讀

ECMA-363-3標(biāo)準(zhǔn)文檔的對應(yīng)的章節(jié)—— 10. 執(zhí)行上下文

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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85448.html

相關(guān)文章

  • js運(yùn)行機(jī)制及異步編程(一)

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

    wudengzan 評論0 收藏0
  • js運(yùn)行機(jī)制及異步編程(一)

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

    happen 評論0 收藏0
  • JavaScript基礎(chǔ)系列---執(zhí)行環(huán)境與作用域鏈

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

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

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

    malakashi 評論0 收藏0
  • 理解JavaScript的核心知識點(diǎn):This

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

    TerryCai 評論0 收藏0

發(fā)表評論

0條評論

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