這篇文章主要介紹“Javascript中的執(zhí)行上下文如何創(chuàng)建”,在日常操作中,相信很多人在Javascript中的執(zhí)行上下文如何創(chuàng)建問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Javascript中的執(zhí)行上下文如何創(chuàng)建”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
成都創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比義馬網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式義馬網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋義馬地區(qū)。費(fèi)用合理售后完善,十多年實(shí)體公司更值得信賴。
這里為了稍微將案例復(fù)雜化一點(diǎn),做了一點(diǎn)點(diǎn)修改,但是并沒有改變原題所考察的點(diǎn)。
function func(value){
getValue = function(){
console.log(value);
};
return this
}
function getValue(){
console.log(5);
}
Func(1).getValue(); //為什么是1呢?
執(zhí)行全局代碼,創(chuàng)建全局執(zhí)行上下文,全局上下文被壓入執(zhí)行上下文棧
ECStack = [ globalContext ];
初始化全局上下文
globalContext = {
VO: {
func: reference to function func(){},
getValue: reference to function getValue(){}
},
Scope: [globalContext.VO],
this: globalContext.VO //全局上下文
}
初始化全局上下文同時(shí)創(chuàng)建了兩個(gè)函數(shù),因此也會保存他們父級作用域鏈在他們的內(nèi)部屬性 [[scope]] 內(nèi)
func.[[scope]] = [
globalContext.VO
];
getValue.[[scope]] = [
globalContext.VO
];
此時(shí)開始執(zhí)行代碼,執(zhí)行到最后的語句時(shí)先執(zhí)行 func 函數(shù),也就創(chuàng)建按步驟 func 函數(shù)執(zhí)行上下文:
復(fù)制函數(shù) [[scope]] 屬性創(chuàng)建作用域鏈
用 arguments 創(chuàng)建活動(dòng)對象
初始化活動(dòng)對象
將活動(dòng)對象壓入 checksfunccope 作用域鏈頂端。
創(chuàng)建this,簡單分析:MemberExpression 值為func,func是一個(gè)函數(shù)對象,理所當(dāng)然是一個(gè)Reference ,其中它的 base value 是 EnvironmentRecord ,所以它的 this 值為 ImplicitThisValue(ref),返回值始終是 undefined ,非嚴(yán)格模式下,其值會被隱式轉(zhuǎn)換為全局對象。
funcContext = {
AO: {
arguments: { // 數(shù)組
0: 1,
length: 1
}
},
Scope: [AO, globalContext.VO],
this: undefined
}
可能有人會有疑問,func 里的 getValue 呢?,因?yàn)樗]有變量申明,因此他其實(shí)是一個(gè)屬性的賦值操作,在后面運(yùn)行時(shí)才會被執(zhí)行。
創(chuàng)建函數(shù)執(zhí)行上下文后壓入執(zhí)行上下文棧
ECStack = [
funcContext,
globalContext
];
函數(shù)開始執(zhí)行,此時(shí)就是為什么最后輸出是1的關(guān)鍵了,第一句賦值操作,那么就需要沿著執(zhí)行上下文去找變量 getValue,那么我們就來看 funcContext 中的作用域,首先找到 funcContext.AO 顯然并不存在 getValue 這一屬性,那么沿著作用域鏈往上找,找到了globalContext.VO ,找到了 getValue ,這時(shí)候就會給全局作用域下的 getValue 屬性重新賦值,賦的是一個(gè)函數(shù)的傳新版本,也就重新創(chuàng)建了函數(shù)作用域,將這個(gè)全新的 getValue 函數(shù)的父級作用域鏈保存在它在他們的內(nèi)部屬性 [[scope]] 內(nèi):
getValue .[[scope]] = [ funcContext.AO, globalContext.VO ];
然后才繼續(xù)返回 this ,查找 funcContext 的 this ,即返回undefined;func 執(zhí)行上下文出棧
ECStack = [ globalContext ];
繼續(xù)執(zhí)行Func(1).getValue()
,前半部分返回了 undefined ,此時(shí)系統(tǒng)隱式轉(zhuǎn)換為全局變量對象,從全局變量對象中找到 getValue 屬性。這時(shí)候我們發(fā)現(xiàn) getValue 早已不是當(dāng)年那個(gè)少年,執(zhí)行全新的 getValue 的函數(shù)執(zhí)行上下文并入棧:
getValueContext = {
AO: {
arguments: { // 數(shù)組
length: 0
}
},
Scope: [ AO, funcContext.AO, globalContext.VO ],
this: undefined
} ECStack = [
getValueContext,
globalContext
];
函數(shù)開始執(zhí)行,發(fā)現(xiàn)她要輸出 value
,沿著作用域去找,getValueContext.AO 中并沒有這個(gè)屬性, 繼續(xù)往下找找到 funcContext.AO(注意!),在形參中 找到了 value 那么就輸出對樣的值,也就輸出了1。函數(shù)執(zhí)行完畢,getValueContext 和 globalContext 相繼出棧并銷毀,代碼運(yùn)行完畢。
到此,關(guān)于“Javascript中的執(zhí)行上下文如何創(chuàng)建”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!