解析示例代码的执行上下文:
let a = 20;
const b = 30;
var c;
function multiply(e, f) {
var g = 20;
return e * f * g;
}
c = multiply(20, 30);
1.
⦿ 当代码运行时,JavaScript 引擎首先创建一个全局执行上下文来执行全局代码。
⦿ 创建阶段的全局上下文就是:
全局执行上下文={
词法环境:{
环境记录:{
Type: "Object",
//标识符绑定在这里
a:<未初始化 >,
b:<未初始化 >,
multiply: < func >
}
outer: <null>,
ThisBinding:<全局对象>
},
变量环境:{
环境记录:{
Type: "Object",
//标识符绑定在这里
c: undefined,
}
outer: <null>,
ThisBinding:<全局对象>
}
}
2.
⦿执行阶段,变量赋值完成。于是,在执行阶段期间,全局执行上下文就变成:
全局执行上下文={
词法环境:{
环境记录:{
Type: "0bject",
//标识符绑定在这里
a: 20,
b: 30,
multiply: < func >
}
outer: <null>,
ThisBinding:<全局对象>
},
变量环境:{
环境记录:{
Type: "0bject",
//标识符绑定在这里
c: undefined,
}
outer: <null>,
ThisBinding:<全局对象>
}
}
3.
⦿当遇到调用函数multiply(20,30)时,就创建一个新的函数执行上下文来执行该函数代码。于是,在创建阶段期间,该函数执行上下文就是这样的:
函数执行上下文={
词法环境:{
环境记录:{
Type: "Declarative",
//标识符绑定在这里
Arguments: {0:20,1: 30,length: 2},
},
outer:<全局词法环境>,
ThisBinding:<全局对象或者undefined>,
},
变量环境:{
环境记录:{
Type: "Declarative" ,
//标识符绑定在这里g: undefined
},
outer:<全局词法环境>,
ThisBinding:<全局对象或者 undefined>
}
}
4.
⦿之后,该执行上下文进入执行阶段,也就是说,该函数内的变量赋值已经完成。于是,在执行阶段期间,该函数执行上下文就是这样的:
函数执行上下文={
词法环境:{
环境记录:{
Type: "Declarative",
//标识符绑定在这里
Arguments: {o: 20,1: 30,length:2},
},
outer:<全局词法环境>,
ThisBinding:<全局对象或者undefined>,
},
变量环境:{
环境记录:{
Type: "Declarative",
//标识符绑定在这里
g:20
},
outer:<全局词法环境>,
ThisBinding:<全局对象或者undefined>
}
}