国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

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

瀏覽:24日期:2023-06-05 16:46:16
一、執(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í)行上下文棧的具體情況,請大家手動代碼練習一下,相信會容易理解透徹。

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

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

我們已經知道,每次調用函數(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ù)都只能聲明

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

(二)執(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í)行上下文及調用堆棧的資料請關注好吧啦網(wǎng)其它相關文章!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 国产精品理论片 | 一区二区三区高清在线 | 免费国产高清精品一区在线 | 欧美日本俄罗斯一级毛片 | 亚洲成人黄色片 | 国产精品成人一区二区 | 久久久久久一级毛片免费野外 | 精品国产三级a在线观看 | 韩国美女激情视频一区二区 | 欧美国产日韩在线 | 57pao强力打造手机版 | 91人人视频国产香蕉 | 成人影院vs一区二区 | 精品久久久久中文字幕日本 | 成人一级片 | 国产自精品在线 | 欧美极品大肚孕妇孕交 | 欧美丝袜xxxxx在线播放 | 92精品国产自产在线观看 | 萌白酱粉嫩jk福利视频在线观看 | a级片在线免费观看 | 一级视频在线播放 | 国产亚洲精品一品区99热 | 国产高清自拍一区 | 草草影院国产第一页 | 丝袜黄色片 | 亚洲精品一区二区三区国产 | 自拍视频区 | 成人国产在线24小时播放视频 | 国产成人毛片毛片久久网 | 国产日韩欧美综合一区二区三区 | 免费在线观看一区二区 | 国产一有一级毛片视频 | 欧美亚洲国产精品久久 | 亚洲精品国产综合一线久久 | 亚洲国产精品日韩在线观看 | 亚洲欧美网站 | 日本成a人片在线观看网址 日本成年人视频网站 | 久久一日本道色综合久 | 国产亚洲高清不卡在线观看 | 亚洲免费中文 |