欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解JavaScript中的執(zhí)行上下文及調(diào)用堆棧

 更新時(shí)間:2021年04月29日 14:43:37   作者:淺笑·  
這篇文章主要介紹了JavaScript中的執(zhí)行上下文及調(diào)用堆棧,對(duì)此感興趣的同學(xué),可以參考下

一、執(zhí)行上下文是什么

代碼運(yùn)行是在一定的環(huán)境之中運(yùn)行的,這個(gè)運(yùn)行環(huán)境我們就成為執(zhí)行環(huán)境,也就是執(zhí)行上下文,按照?qǐng)?zhí)行環(huán)境不同,我們可以分為三類(lèi):

全局執(zhí)行環(huán)境:代碼首次執(zhí)行時(shí)候的默認(rèn)環(huán)境

函數(shù)執(zhí)行環(huán)境:每當(dāng)執(zhí)行流程進(jìn)入到一個(gè)函數(shù)體內(nèi)部的時(shí)候

Eval執(zhí)行環(huán)境:當(dāng)eval函數(shù)內(nèi)部的文本執(zhí)行的時(shí)候

二、執(zhí)行上下文棧是什么

既然是‘棧',那就得符合‘棧'的特性,即數(shù)據(jù)結(jié)構(gòu)是先進(jìn)后出。下面我們看一段代碼:

function cat(a){
    if(a<0){
        return false;
    }
    console.log('入棧:'+a);
    cat(a-1);
    console.log('出棧:'+a);
}
cat(3);
// 入棧:3
// 入棧:2
// 入棧:1
// 入棧:0
// 出棧:0
// 出棧:1
// 出棧:2
// 出棧:3

我們來(lái)分析上面的代碼的執(zhí)行過(guò)程:

①瀏覽器加載時(shí),程序進(jìn)入全局執(zhí)行上下文,將其壓入一個(gè)棧內(nèi)(第一個(gè)進(jìn)入的,所以最底層);該執(zhí)行上下文下只有一個(gè)函數(shù)cat、cat調(diào)用、參數(shù)3;

②程序進(jìn)入cat函數(shù)內(nèi),即進(jìn)入該函數(shù)執(zhí)行上下文,也將其壓入棧內(nèi)(第二個(gè)進(jìn)入的,所以倒數(shù)第二層),因?yàn)閰?shù)為3大于0,繼續(xù)往下執(zhí)行,輸出'入棧:3';

③程序繼續(xù)執(zhí)行,調(diào)用函數(shù)cat,再次進(jìn)入新的函數(shù)執(zhí)行上下文,繼續(xù)壓入棧內(nèi)(第三個(gè)進(jìn)入,倒數(shù)第三層),參數(shù)為a-1,循環(huán)②步驟;這里,需要注意的是,因?yàn)檎{(diào)用了函數(shù)cat(a-1),導(dǎo)致下一行代碼'出棧:a'(此時(shí)a仍為3),也就是'出棧:3'暫時(shí)擱淺起來(lái),存在棧內(nèi)倒數(shù)第二層

④不斷重復(fù)②③步驟,以次輸出'入棧:2'、'入棧:1'、'入棧:0';同時(shí)被擱淺的有'出棧:2'(棧內(nèi)倒數(shù)第三層)、'出棧:1(棧內(nèi)倒數(shù)第四層)'、'出棧:0(棧內(nèi)倒數(shù)第五層)';

⑤按照棧的特性,被擱淺起來(lái)的4個(gè)輸出項(xiàng):以次輸出'入棧:3'、'入棧:2'、'入棧:1'、'入棧:0';
以上就是執(zhí)行上下文棧的具體情況,請(qǐng)大家手動(dòng)代碼練習(xí)一下,相信會(huì)容易理解透徹。

三、執(zhí)行上下文棧的過(guò)程細(xì)節(jié)

我們已經(jīng)知道,每次調(diào)用函數(shù)都會(huì)執(zhí)行一個(gè)新的上下文,每個(gè)執(zhí)行上下文都分為兩個(gè)階段:創(chuàng)建階段、執(zhí)行階段
創(chuàng)建階段:指的是程序調(diào)用函數(shù),但代碼未執(zhí)行時(shí)的階段;
執(zhí)行階段:指的是變量分配、函數(shù)執(zhí)行等代碼執(zhí)行階段;

(一)創(chuàng)建階段

該階段會(huì)調(diào)用函數(shù)數(shù)時(shí),創(chuàng)建一個(gè)執(zhí)行上下文對(duì)象(executionContextObj),該對(duì)象又包含了三個(gè)對(duì)象,分別是作用域鏈對(duì)象(scopeChain)、變量對(duì)象(variableObject,簡(jiǎn)稱(chēng)VO)、this對(duì)象,其中VO包括變量聲明(variable)、函數(shù)聲明(function)、參數(shù)(arguments)等。
這三個(gè)對(duì)象分別是在三個(gè)步驟創(chuàng)建的:
步驟1:初始化作用域鏈(scopeChain),開(kāi)辟棧內(nèi)存

步驟2:創(chuàng)建參數(shù)、函數(shù)、變量

步驟3:決定上下文的'this'的值

結(jié)合代碼來(lái)進(jìn)一步分析一下上面的步驟:

function cat(name) {
    var a = '年年';
    var b = function () {};
    this.name = name;
    function c() {
        console.log(this.name);
    }
    c();
}
cat('有魚(yú)');

這段代碼在調(diào)用函數(shù) cat('有魚(yú)')時(shí),執(zhí)行上下文是處于 創(chuàng)建階段的,代碼解析為:

cat執(zhí)行上下文對(duì)象 = {
    scopeChain: { ... },// 1.創(chuàng)建作用域鏈,開(kāi)辟棧內(nèi)存
    variableObject: { 2.創(chuàng)建變量對(duì)象
        arguments: {  // 2.1 解析參數(shù)
            0: '有魚(yú)',
            length: 1
        },
        name: '有魚(yú)',  // 2.1 解析參數(shù),創(chuàng)建形參名稱(chēng),并進(jìn)行參數(shù)賦值
        c: function c()  // 2.2 找到函數(shù)聲明c,并將c作為屬性,function c作為值
        a: undefined,  // 2.3 找到變量聲明a,初始化為undefined,該階段只看聲明部分,不進(jìn)行賦值
        b: undefined   // 2.3 找到變量聲明b,初始化為undefined,該階段只看聲明部分,不進(jìn)行賦值
    },
    this: {  3.創(chuàng)建this對(duì)象
        this:cat('有魚(yú)') // 3.1 指向此次調(diào)用的對(duì)象
        name:undefined // 3.2 對(duì)象屬性name的初始化為undefined
    };
    c() //又進(jìn)入函數(shù)c執(zhí)行上下文,跟cat函數(shù)一樣,暫不展開(kāi) 
}

通過(guò)代碼解析我們可以得出以下結(jié)論

①三個(gè)步驟順序不能亂
②VO步驟內(nèi),先執(zhí)行函數(shù)聲明,再執(zhí)行變量聲明
③只有參數(shù)可以在此階段進(jìn)行賦值,變量、函數(shù)都只能聲明

(二)執(zhí)行階段

該階段js解釋器執(zhí)行上下文中的函數(shù)代碼,逐行運(yùn)行js代碼,并給變量賦值;
還是結(jié)合代碼來(lái)分析:

cat執(zhí)行上下文對(duì)象 = {
    scopeChain: { ... },
    variableObject: { 
        arguments: { 
            0: '有魚(yú)',
            length: 1
        },
        name: '有魚(yú)', 
        c: function c(),
        a: '年年',  // 變量a進(jìn)行賦值
        b: function b   // 變量b進(jìn)行賦值
    },
    this: {  3.創(chuàng)建this對(duì)象
        this:cat('有魚(yú)') 
        name:'有魚(yú)' // 對(duì)象屬性name進(jìn)行賦值
    }
}

以上就是詳解JavaScript中的執(zhí)行上下文及調(diào)用堆棧的詳細(xì)內(nèi)容,更多關(guān)于JavaScript中的執(zhí)行上下文及調(diào)用堆棧的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解PHP后期靜態(tài)綁定分析與應(yīng)用

    詳解PHP后期靜態(tài)綁定分析與應(yīng)用

    這篇文章給大家總結(jié)了PHP后期靜態(tài)綁定分析與應(yīng)用的相關(guān)知識(shí)點(diǎn),對(duì)此有興趣的朋友可以學(xué)習(xí)下。
    2018-03-03
  • javascript模擬C#格式化字符串

    javascript模擬C#格式化字符串

    學(xué)習(xí)C#的朋友都知道format()這個(gè)方法,本文給大家介紹在javascript中如何實(shí)現(xiàn)此操作,js模擬C#字符串格式化操作,需要的盆友一起學(xué)習(xí)吧
    2015-08-08
  • js HTML5 Canvas繪制轉(zhuǎn)盤(pán)抽獎(jiǎng)

    js HTML5 Canvas繪制轉(zhuǎn)盤(pán)抽獎(jiǎng)

    這篇文章主要為大家詳細(xì)介紹了js HTML5 Canvas繪制轉(zhuǎn)盤(pán)抽獎(jiǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • javascript 冒號(hào) 使用說(shuō)明

    javascript 冒號(hào) 使用說(shuō)明

    雖然之前寫(xiě)過(guò)不少的javascirpt的腳本,但是對(duì)冒號(hào):卻不甚了了,感覺(jué)即陌生又熟悉,沒(méi)辦法老毛病又犯了,不把問(wèn)題搞清楚那個(gè)(:)
    2009-06-06
  • 將json當(dāng)數(shù)據(jù)庫(kù)一樣操作的javascript lib

    將json當(dāng)數(shù)據(jù)庫(kù)一樣操作的javascript lib

    使用javascript操作JSON的類(lèi)庫(kù)TAFFY DB,具體介紹了:查詢數(shù)據(jù)、添加數(shù)據(jù)、刪除數(shù)據(jù)、修改數(shù)據(jù)。
    2013-10-10
  • 最新評(píng)論