var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
当开始执行上述代码时,会创建全局执行上下文;
ECStack.push(global_EC);
ECStrict = [
global_EC
]
2. 初始化全局执行上下文(创建阶段);
global_EC = {
VO:window,
// current scope + scopes of all its parents
// 这里将 scope 用 VO 表示,是因为在作用域中查找变量,其实就是从变量对象中查找,变量对象可以理解为作用域的实体
scope: [VO],
this: window
}
window = {
// 内置全局属性和函数
... ,
// 声明的全局变量和函数
checkscope: reference to function checkscope(){},
scope: undefined,
}
3. 进入执行阶段,执行代码。当开始执行`checkscope`函数时,创建该函数的执行上下文。
ECStack.push(checkscope_EC);
ECStrict = [
global_EC,
checkscope_EC
]
4. 初始化`checkscope`函数的执行上下文(创建阶段)。
checkscope_EC = {
VO: {
arguments: {
length: 0
},
scope: undefined,
f: reference to function f(){},
}
// current scope + scopes of all its parents
scope: [global_EC.VO, VO],
// 非严格模式
this: window
}
5. 进入执行阶段,执行代码。当开始执行` f `函数时,执行过程同上,创建并初始化` f `函数的执行上下文;
ECStack.push(f_EC);
ECStrict = [
global_EC,
checkscope_EC,
f_EC
]
f_EC = {
VO: {
arguments: {
length: 0
}
},
// current scope + scopes of all its parents
scope: [global_EC.VO, checkscope_EC.VO, VO],
// 非严格模式
this: window
}
执行上下文的生命周期
执行上下文的生命周期包括两个阶段:
我们以下面这段代码为例,分析执行上下文的整个生命周期。(示例来源于参考文章)
ECStrict = [ global_EC ]
global_EC = { VO:window, // current scope + scopes of all its parents // 这里将 scope 用 VO 表示,是因为在作用域中查找变量,其实就是从变量对象中查找,变量对象可以理解为作用域的实体 scope: [VO], this: window }
window = { // 内置全局属性和函数 ... , // 声明的全局变量和函数 checkscope: reference to function checkscope(){}, scope: undefined, }
ECStack.push(checkscope_EC);
ECStrict = [ global_EC, checkscope_EC ]
checkscope_EC = { VO: { arguments: { length: 0 }, scope: undefined, f: reference to function f(){}, } // current scope + scopes of all its parents scope: [global_EC.VO, VO], // 非严格模式 this: window }
ECStack.push(f_EC);
ECStrict = [ global_EC, checkscope_EC, f_EC ]
f_EC = { VO: { arguments: { length: 0 } }, // current scope + scopes of all its parents scope: [global_EC.VO, checkscope_EC.VO, VO], // 非严格模式 this: window }
ECStack.pop();
ECStrict = [ global_EC, checkscope_EC ]
ECStack.pop();
ECStrict = [ global_EC ]