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

資訊專欄INFORMATION COLUMN

原生JS大揭秘—JS代碼底層運(yùn)行原理

xiongzenghui / 2154人閱讀

摘要:是一種基于對象的動態(tài)弱類型腳本語言以下簡稱,是一種解釋型語言,和其他的編程語言不同,如等編譯型語言,這些語言在代碼執(zhí)行前會進(jìn)行通篇編譯,先編譯成字節(jié)碼機(jī)器碼。然后在執(zhí)行。

JavaScript是一種基于對象的動態(tài)、弱類型腳本語言(以下簡稱JS),是一種解釋型語言,和其他的編程語言不同,如java/C++等編譯型語言,這些語言在代碼執(zhí)行前會進(jìn)行通篇編譯,先編譯成字節(jié)碼(機(jī)器碼)。然后在執(zhí)行。而JS不是這樣做的,JS是不需要編譯成中間碼,而是可以直接在瀏覽器中運(yùn)行,JS運(yùn)行過程可分為兩個階段,編譯和執(zhí)行。(可參考你不知道的JS這本書),當(dāng)JS控制器轉(zhuǎn)到一段可執(zhí)行的代碼時(這段可執(zhí)行代碼就是編譯階段生成的),會創(chuàng)建與之對應(yīng)的執(zhí)行上下文(Excution Context簡稱EC)。執(zhí)行上下文可以理解為執(zhí)行環(huán)境(執(zhí)行上下文只能由JS解釋器創(chuàng)建,也只能由JS解釋器使用,用戶是不可以操作該"對象"的)。 JS中的執(zhí)行環(huán)境分為三類:

全局環(huán)境:當(dāng)JS引擎進(jìn)入一個代碼塊時,如遇到標(biāo)簽,就是進(jìn)入一個全局執(zhí)行環(huán)境

函數(shù)環(huán)境:當(dāng)一個函數(shù)被調(diào)用時,在函數(shù)內(nèi)部就形成了一個函數(shù)執(zhí)行環(huán)境

eval():把字符串單做JS代碼執(zhí)行,不推薦使用

在一段JS代碼中可能會產(chǎn)生多個執(zhí)行上下文,在JS中用棧這種數(shù)據(jù)結(jié)構(gòu)來管理執(zhí)行上下文,棧的特點(diǎn)是“先進(jìn)后出,后進(jìn)先出”,這種棧稱之為執(zhí)行上下文棧(Excution Context Stack 簡稱ECS)。 執(zhí)行上下文的特點(diǎn)

棧底永遠(yuǎn)是全局執(zhí)行上下文,有且僅有一個

全局執(zhí)行上下文只有在瀏覽器關(guān)閉時,才會彈出棧

其他的執(zhí)行上下文的數(shù)量沒有限制

棧頂永遠(yuǎn)是當(dāng)前活動執(zhí)行上下文,其余的都處于等待狀態(tài)中,一旦執(zhí)行完畢,立即彈出棧,然后控制權(quán)交回下一個執(zhí)行上下文

函數(shù)只有在每次被調(diào)用時,才會為其創(chuàng)建執(zhí)行上下文,函數(shù)被聲明時是沒有的。

執(zhí)行上下文可以形象的理解為一個普通的JS對象,一個執(zhí)行上下文的生命周期大概包含兩個階段:

創(chuàng)建階段

此階段主要完成三件事件,1、創(chuàng)建變量對象 2、建立作用域鏈 3、確定this指向

執(zhí)行階段

此階段主要完成變量賦值、函數(shù)調(diào)用、其他操作

變量對象(VO)的創(chuàng)建過程

1、根據(jù)函數(shù)參數(shù),創(chuàng)建并初始化arguments對象,

AO={
    //創(chuàng)建arguments對象,注意這里還沒有添加任何屬性
    arguments:{
        length:0 //設(shè)置初始值為0
    }
}

2、查找function函數(shù)聲明,在變量對象上添加屬性,屬性名就是函數(shù)名,屬性值就是函數(shù)的引用值,如果已經(jīng)存在同名的,則直接覆蓋

3、查找var變量聲明(查找變量時,會把函數(shù)的參數(shù)等價于var聲明,所以在AO中也會添加和參數(shù)名一樣的屬性,初始值也是undefined),在變量對象添加屬性,屬性名就是變量名,屬性值是undefined,如果已經(jīng)存在同名的,則不處理
查找var變量聲明時,是從函數(shù)的參數(shù)開始的,此時函數(shù)的參數(shù)定義相當(dāng)于如下代碼

   Foo(a, b, c){
       //-------------------這一部分是隱藏的我們無法顯示看到-------------------------
       var a=1; //傳入?yún)?shù)
       var b=2; //傳入?yún)?shù)
       var c; //沒有傳入?yún)?shù)
       //--------------------------------------------
       var name="kity"
         
       function bar(){}
       
   }
   
   Foo(11,22)
   

如果存在同名標(biāo)識符(函數(shù)、變量),則函數(shù)可以覆蓋變量,函數(shù)的優(yōu)先級高于變量 變量對象(OV)激活對象(AO)是同一個東西,在全局執(zhí)行上下文中是VO,在函數(shù)執(zhí)行上下文中是AO,因為VO在全局執(zhí)行上下文中可以直接訪問,但是在函數(shù)執(zhí)行上下文中是不能直接訪問的,此時有AO扮演VO的角色

以如下代碼為例

var g_name="tom";
var g_age=20;
function g_fn(num){
    var l_name="kity";
    var l_age=18;
    function l_fn(){
        console.log(g_name + "===" + l_name + "===" + num);
    }
}
g_fn(10);
編譯階段

當(dāng)JS控制器轉(zhuǎn)到這一段代碼時,會創(chuàng)建一個執(zhí)行上下文,G_EC
執(zhí)行上下文的結(jié)構(gòu)大概如下:

G_EC = {
    VO          : {},
    Scope_chain : [],
    this        : {}
}

/* VO的結(jié)構(gòu)大概 */
VO = {
    g_name : undefined,
    g_age  : undefined,
    g_fn   : <函數(shù)在內(nèi)存中引用值>
}

/* Scope_chain的大概結(jié)構(gòu)如下 */
Scope_chain = [ G_EC.VO ] // 數(shù)組中第一個元素是當(dāng)前執(zhí)行上下文的VO,第二個是父執(zhí)行上下文的VO,最后一個是全局執(zhí)行上下文的VO,在執(zhí)行階段,會沿著這個作用域鏈一個一個的查找標(biāo)識符,如果查到則返回,否知一直查找到全局執(zhí)行上下文的VO

/* this */
this = undefined // 此時this的值是undefined

執(zhí)行上下文一旦創(chuàng)建完畢,就立馬被壓入函數(shù)調(diào)用棧中,此時解釋器會悄悄的做一件事情,就是給當(dāng)前VO中的函數(shù)添加一個內(nèi)部屬性[[scope]],該屬性指向上面的作用域鏈。

g_fn.scope = [ global_EC.VO ] // 該scope屬性只能被JS解釋器所使用,用戶無法使用
執(zhí)行階段(此階段VO->AO

一行一行執(zhí)行代碼,當(dāng)遇到一個表達(dá)式時,就會去當(dāng)前作用域鏈的中查找VO對象,如果找到則返回,如果找不到,則繼續(xù)查找下一個VO對象,直至全局VO對象終止。
此階段可以有變量賦值,函數(shù)調(diào)用等操作,當(dāng)解釋器遇到g_fn()時,就知道這是一個函數(shù)調(diào)用,然后立即為其創(chuàng)建一個函數(shù)執(zhí)行上下文,fn_EC,該上下文fn_EC同樣有兩個階段
分別是創(chuàng)建階段和執(zhí)行階段。
在創(chuàng)建階段,對于函數(shù)的執(zhí)行上下文,首先會從函數(shù)的參數(shù)可以逐行執(zhí)行,

查找function函數(shù)聲明

查找var變量聲明

關(guān)于全局執(zhí)行上下文的VO對象分析:


各個瀏覽器測試情況如下:

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

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

相關(guān)文章

  • 原生JS揭秘—看清JS繼承本質(zhì)

    摘要:繼承理論源于生活又高于生活在中繼承,和現(xiàn)實生活中繼承是相似的如兒子繼承父親財產(chǎn)子女的生理特性有父母的特性身高膚色性格等等只是一定比例上是這樣的,不是絕對的一樣中繼承方法有以下幾種本質(zhì)區(qū)別方法特別注意是本質(zhì)區(qū)別冒充繼承也稱之為借用構(gòu)造函數(shù)這種 JS繼承 理論源于生活、又高于生活 在JS中繼承,和現(xiàn)實生活中繼承是相似的 如:兒子繼承父親財產(chǎn)、子女的生理特性有父母的特性(身高、膚色、性格...

    sutaking 評論0 收藏0
  • 原生JS揭秘—撩開this的面紗

    摘要:隨著函數(shù)使用場景的不同,而發(fā)生變化。是當(dāng)前執(zhí)行上下文中的一部分。在中新增了該方法也是強(qiáng)制更改指向。但是和的區(qū)別是更改后不會立即執(zhí)行,它會返回一個新函數(shù)。 this何意?在英文中this是一個人稱代詞,表示這個的,具體指哪個?不確定,只有在具體的語境中才可確定,在編程語言中this也有同樣的類似特性。在js中this是一個關(guān)鍵字,它不能被當(dāng)做變量、屬性,也不可以進(jìn)行賦值操作。this 隨...

    Brenner 評論0 收藏0
  • 原生JS揭秘—同步與異步

    摘要:中任務(wù)分類同步異步同步任務(wù)異步任務(wù)中異步類型定時任務(wù)網(wǎng)絡(luò)請求回調(diào)函數(shù)事件綁定只能傳入一個參數(shù)未完待續(xù) JS中任務(wù)分類 同步 異步 同步任務(wù) 異步任務(wù) JS中異步類型 定時任務(wù) 網(wǎng)絡(luò)請求 回調(diào)函數(shù) 事件綁定 Promise(resolve只能傳入一個參數(shù)) 未完待續(xù)...

    不知名網(wǎng)友 評論0 收藏0
  • 原生JS揭秘—原型鏈

    原型鏈showImg(https://segmentfault.com/img/bVboNT0?w=1332&h=1333);

    macg0406 評論0 收藏0
  • 原生JS揭秘—事件循環(huán)機(jī)制Event Loop

    事件循環(huán)機(jī)制Event Loop showImg(https://segmentfault.com/img/bVbozlD?w=1178&h=564);

    SolomonXie 評論0 收藏0

發(fā)表評論

0條評論

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