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

資訊專欄INFORMATION COLUMN

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

imingyu / 2466人閱讀

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

概要

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

定義

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

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

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

可執(zhí)行代碼類型

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

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

ECStask = [ ];

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

全局代碼

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

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

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

一旦控制器進(jìn)入函數(shù)代碼(各類函數(shù)),就會(huì)有新的元素會(huì)被壓棧到ECStack。要注意的是:實(shí)體函數(shù)代碼并不包括內(nèi)部函數(shù)的代碼。如下所示,我們調(diào)用一個(gè)函數(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)前活動(dòng)的執(zhí)行上下文時(shí),ECStack就會(huì)被執(zhí)行對(duì)應(yīng)的退棧操作——先進(jìn)后出——和傳統(tǒng)的棧實(shí)現(xiàn)一致。同樣的,當(dāng)拋出未捕獲的異常時(shí),也會(huì)退出一個(gè)或者多個(gè)執(zhí)行上下文,ECStack也會(huì)做相應(yīng)的退棧操作。待這些代碼完成之后,ECStack中就只剩下一個(gè)執(zhí)行上下文(globalContext)——直到整個(gè)程序結(jié)束。

Eval代碼

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

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

ECStack會(huì)被修改為:

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

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é)

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

擴(kuò)展閱讀

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85448.html

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

    TerryCai 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<