var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
具体执行分析
执行过程:
1.执行了全局代码,创建了全局上下文,全局上下文被压入执行上下文栈中
ECStack = [
globalContext
];
2.全局上下文初始化
globalContext = {
VO: [global],
Scope: [globalContext.VO],
this: globalContext.VO
}
初始化的同时,checkscope函数被创建,保存作用域链到函数的内部属性[[scope]]
checkscope.[[scope]] = [
globalContext.VO
];
3.执行checkscope函数,创建checkscope函数执行上下文,checkscope函数执行上下文被压入执行上下文栈中
ECStach = [
checkscopeContext,
globalContext
];
4.checkscope函数执行上下文初始化:
- 复制函数[[scope]]属性创建作用域链
- 用arguments创建活动对象
- 初始化活动对象,加入形参、函数声明、变量声明
- 将活动对象压入checkscope作用域链的顶端
同时f函数被创建,保存作用域链到f函数的内部属性[[scope]]
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope: undefined,
f: reference to function f(){}
},
Scope: [AO, globalContext.VO],
this: undefined
}
5.执行f函数,创建f函数执行上下文,f函数执行上下文被压入执行上下文栈
ECStack = [
fContext,
checkscopeContext,
globalContext
];
6.f函数执行上下文初始化:
- 复制函数[[scope]]属性创建作用域链
- 用arguments创建活动对象
- 初始化活动对象,加入形参、函数声明、变量声明
- 将活动对象压入f作用域链顶端
fContext = {
AO: {
arguments: {
length: 0
}
},
Scope: [AO, checkscopeContext.AO, globalContext.VO],
this: undefined
}
7.f函数执行,沿着作用域链查找scope的值,返回scope的值
8.f函数执行完毕,f函数上下文从执行上下文栈中弹出
ECStack = [
checkscopeContext,
globalContext
];
9.checkscope函数执行完毕,checkscope执行上下文从执行上下文栈中弹出
ECStack = [
globalContext
];
整个过程结束。
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
具体执行分析
1.执行全局代码,创建全局上下文,全局上下文被压入执行上下文栈
ECStack = [
globalContext
];
2.全局上下文初始化
globalContext = {
VO: [global],
Scope: [globalContext.VO],
this: globalContext.VO
}
初始化的同时,checkscope函数被创建,保存作用域链到函数的内部属性[[scope]]
checkscope.[[scope]] = [
globalContext.VO
]
3.执行checkscope函数,创建checkscope函数执行上下文,checkscope函数执行上下文被压入执行上下文栈
ECStack = [
checkscopeContext,
globalContext
];
4.checkscope函数执行上下文初始化:
- 复制函数[[scope]]属性创建作用域链
- 用arguments创建活动对象
- 初始化活动对象,即加入形参、函数声明、变量声明
- 将活动对象压入checkscope作用域链顶端
同时f函数被创建,保存作用域链到f函数的内部属性[[scope]]
checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope: undefined,
f: reference to function f(){}
},
Scope: [AO, globalContext.VO],
this: undefined
}
5.checkscope函数执行完毕,checkscope函数上下文从执行上下文栈中弹出
ECStack = [
globalContext
]
6.执行f函数,创建f函数执行上下文,f函数执行上下文被压入执行上下文栈
ECStack = [
fContext,
globalContext
]
7.f函数执行上下文初始化
- 复制函数[[scope]]属性创建作用域链
- 用arguments创建活动对象
- 初始化活动对象,加入形参、函数声明、变量声明
- 将活动对象压入f作用域链顶端
fContext = {
AO: {
arguments: {
length: 0
}
},
Scope: [AO, checkscopeContext.AO, globalContext.VO],
this: undefined
}
8.f函数执行,沿着作用域链查找scope的值,返回scope的值
9.f函数执行完毕,f函数上下文从执行上下文栈中弹出
ECStack = [
globalContext
];
整个流程结束。
摘自冴羽大佬的博客JavaScript的深入系列
https://github.com/mqyqingfeng/Blog