最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

函數(shù)執(zhí)行環(huán)境:每當執(zhí)行流程進入到一個函數(shù)體內部的時候

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

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

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

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

我們來分析上面的代碼的執(zhí)行過程:

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

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

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

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

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

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

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

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

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

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

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

結合代碼來進一步分析一下上面的步驟:

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

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

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

通過代碼解析我們可以得出以下結論

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

(二)執(zhí)行階段

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

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

以上就是詳解JavaScript中的執(zhí)行上下文及調用堆棧的詳細內容,更多關于JavaScript中的執(zhí)行上下文及調用堆棧的資料請關注腳本之家其它相關文章!

相關文章

  • 使用AJAX實現(xiàn)Web頁面進度條的實例分享

    使用AJAX實現(xiàn)Web頁面進度條的實例分享

    這篇文章主要介紹了使用AJAX實現(xiàn)Web頁面進度條的實例分享,利用AJAX的異步來顯示服務器端的處理進度是當下比較流行的做法,需要的朋友可以參考下
    2016-05-05
  • js canvas實現(xiàn)五子棋小游戲

    js canvas實現(xiàn)五子棋小游戲

    這篇文章主要為大家詳細介紹了js canvas實現(xiàn)五子棋小游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • JavaScript實現(xiàn)動態(tài)生成表格

    JavaScript實現(xiàn)動態(tài)生成表格

    這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)動態(tài)生成表格,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • 如何在一個頁面顯示多個百度地圖

    如何在一個頁面顯示多個百度地圖

    經(jīng)常有人問,百度地圖JavaScript API能在同一頁面顯示多個地圖嗎?當然可以啊,為什么不可以呢?地圖之于頁面無非就是個div,我們可以在頁面顯示多個div,自然也可以顯示多個地圖。
    2013-04-04
  • fix-ie5.js擴展在IE5下不能使用的幾個方法

    fix-ie5.js擴展在IE5下不能使用的幾個方法

    fix-ie5.js擴展在IE5下不能使用的幾個方法...
    2007-08-08
  • javascript彈出頁面回傳值的方法

    javascript彈出頁面回傳值的方法

    這篇文章主要介紹了javascript彈出頁面回傳值的方法,實例分析了由a1.html彈出的b1.html回傳值的實現(xiàn)方法,非常具有實用價值,需要的朋友可以參考下
    2015-01-01
  • 原生javascript實現(xiàn)簡單的datagrid數(shù)據(jù)表格

    原生javascript實現(xiàn)簡單的datagrid數(shù)據(jù)表格

    這篇文章主要介紹了原生javascript實現(xiàn)簡單的datagrid數(shù)據(jù)表格的方法,效果十分棒,需要的朋友可以參考下
    2015-01-01
  • 微信小程序input、textarea層級過高穿透的問題解決

    微信小程序input、textarea層級過高穿透的問題解決

    微信小程序原生組件camera、canvas、input、live-player、live、pusher、map、textarea、video的層級是最高的,那么如何解決微信小程序input、textarea層級過高穿透,本文就詳細的介紹一下
    2021-11-11
  • 用javascript獲取textarea中的光標位置

    用javascript獲取textarea中的光標位置

    Javascript一向以他的靈活隨意而著稱,這也使得它的功能可以非常的強大,而由于沒有比較好的調試工具,又使得它使用起來困難重重,尤其使對于一些初學者,更是感覺到無從下手。今天探討的問題是用javascript獲取textarea中光標的位置。
    2008-05-05
  • JavaScript中的偽數(shù)組用法及說明

    JavaScript中的偽數(shù)組用法及說明

    這篇文章主要介紹了JavaScript中的偽數(shù)組用法及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02

最新評論

惠来县| 北碚区| 淮南市| 左贡县| 石首市| 邓州市| 安阳市| 鄂伦春自治旗| 会泽县| 布尔津县| 晋中市| 绵阳市| 高清| 盐池县| 富平县| 五莲县| 宜阳县| 利津县| 陇川县| 安龙县| 六枝特区| 安图县| 汕头市| 苗栗县| 姚安县| 珲春市| 射洪县| 南川市| 义马市| 内黄县| 沁水县| 和田县| 岳阳县| 元朗区| 基隆市| 陆良县| 泗阳县| 井陉县| 大竹县| 大洼县| 清丰县|