JavaScript模拟分析执行上下文
本文最后更新于
2018-02-01, 文中内容可能已过时,请注意甄别~
JavaScript模拟分析执行上下文⌗
思考题⌗
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
两段代码都会打印’local scope’。虽然两段代码执行的结果一样,但是两段代码究竟有哪些不同呢?
具体执行分析⌗
我们首先分析第一段代码: 1.执行全局代码, 创建全局执行上下文, 全局上下文被压入 ECStack 中
ECStack = [
globalContext
];
2.全局山下文初始化
globalContext = {
VO: [global, scope, checkscope],
Scope: [globalContext.VO],
this: globalContext.VO
}
2.全局上下文初始化的同时, checkscope 函数被创建, 保存作用域链到函数的内部属性 [[scope]]
checkscope.[[scope]] = [
globalContext.VO
]
3.执行 checkscope 函数执行上下文, checkscope函数执行上下文被压入ECStack中
ECStack = [
checkscopeContext,
globalContext
]
4.checkscope 函数执行上下文初始化:
1.复制函数[[scope]] 属性创建作用域链, 2.用 arguments 创建活动对象, 3.初始化活动对象, 即加入形参、函数声明、变量声明, 4.将活动对象压入 checkscope 作用域链顶端。
同时f函数被创建,保存到作用域链到f函数的内部属性[[scope]]
// 严格模式下 this 为 undefined,在非严格模式下指向window
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope: undefined,
f: reference to function f(){}
},
Scope: [AO, globalContext.VO],
this: undefined
}
5.执行f函数,创建f函数执行上下文,f函数执行上下文被压入ECStack中
ECStack = [
fContext,
checkscopeContext,
globalContext
]
6.f函数执行上下文初始化,以下和步骤四相同:
1.复制函数[[scope]] 属性创建作用域链, 2.用 arguments 创建活动对象, 3.初始化活动对象, 即加入形参、函数声明、变量声明, 4.将活动对象压入 f 作用域链顶端。
fContext = {
AO: {
arguments: {
length: 0
},
scope: [AO, checkscopeContext.AO, globalContext,VO],
this: undefined
}
}
7.f 函数执行完毕,沿着作用域链查找 scope 值,返回 scope 值
8.f函数执行完毕,f函数上下文从执行上下文栈(ECStack)中弹出
ECStack = [
checkscopeContext,
globalContext
];
9.checkscope 函数执行完毕,checkscope 执行上下文从ECStack中弹出
ECStack = [
globalContext
];
至此,执行过程结束。
Read other posts