執(zhí)行上下文的創(chuàng)建時機:
當(dāng)調(diào)用一個函數(shù)時(激活),一個新的執(zhí)行上下文就會被創(chuàng)建纹安。
執(zhí)行上下文的生命周期
一個執(zhí)行上下文的生命周期可以分為兩個階段在岂,創(chuàng)建階段和執(zhí)行階段。
創(chuàng)建階段:
Paste_Image.png
執(zhí)行階段:
Paste_Image.png
注意:在檢查變量聲明階段技即,如果遇到同名的變量名時,則直接跳過晌柬。因為同名的變量名可能是在檢查函數(shù)聲明時創(chuàng)建的姥份,跳過是為了避免覆蓋掉已聲明的函數(shù)。
舉個小例子年碘,看一下上下文從創(chuàng)建到執(zhí)行的過程澈歉。
(function demo(){
console.log("執(zhí)行前a的值為:"+a);
foo();
function foo(){
console.log("foo declare");
}
var foo = function(){
console.log("foo expression");
}
foo();
var a = 20;
console.log("執(zhí)行后a的值為:"+a);
})()
//結(jié)果:
執(zhí)行前a的值為:undefined
foo declare
foo expression
執(zhí)行后a的值為:20
解析
- 執(zhí)行上下文創(chuàng)建:
demoEC = {
// 變量對象
VO: {},
scopeChain: {},
this: {}
}
創(chuàng)建變量對象階段:
// VO 為 Variable Object的縮寫,即變量對象
VO = {
arguments: {...},
foo: <foo reference> // 表示foo的地址引用,var聲明的foo變量會跳過不覆蓋
a: undefined
}
- 執(zhí)行階段:
VO->AO //變量對象變?yōu)榛顒訉ο?AO={
arguments:{...},
foo:<foo reference> //函數(shù)表達式賦值
a:20
}
執(zhí)行順序:
(function demo(){
function foo(){
console.log("foo declare");
}
var a;
console.log("a執(zhí)行前的值為:"+a);
foo();
foo = function(){
console.log("foo expression");
}
foo();
a = 20;
console.log("a執(zhí)行后的值為:"+a);
})()