「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战」
ES6中的执行上下文(execution context)
ES6将执行上下文(execution context)分为俩个阶段,分别创建阶段与执行阶段。
创建阶段
在创建阶段主要分为三个步骤,确定this(Binding This)、创建词法环境(LexicalEnvironment)、创建变量环境(VariableEnvironment)。
确定this(Binding This)
在确定this这一步骤中,如果是在全局执行上下文中,this是执行全局对象的。在浏览器环境中是window对象、在node环境中是指向global对象。
而在函数执行上下文中this指向就取决于调用方式了,简单来说就是谁使用指向谁,具体的可以看下之前的文章了解this的四种形式,看完这篇文章就足够了!!!。
let obj = {
fun:function(){
console.log(this) // obj
}
}
obj.fun()
创建词法环境(LexicalEnvironment)
词法环境(LexicalEnvironment)分为环境记录(EnvironmentRecor)与外部环境记录(OuterEnvironmentRecor)。这里的外部环境记录(OuterEnvironmentRecor)就有点类似之前所说的作用域链了。
根据全局执行上下文与函数执行上下文的不同分为全局词法环境与函数词法函数。
全局词法环境:
GlobalExectionContext = { // 全局执行上下文
LexicalEnvironment: { // 词法环境
EnvironmentRecor: {
},
OuterEnvironmentRecor: null
}
}
函数词法环境
FunctionExectionContext = { // 函数环境
LexicalEnvironment: { // 函数词法环境
EnvironmentRecord: { // 类型为声明性环境记录
},
outer: Global // 或者是有关的外部函数环境
}
};
创建变量环境(VariableEnvironment)
变量环境(VariableEnvironment)其实与词法环境(LexicalEnvironment)类似。主要用于存放var声明的变量。
执行阶段
创建阶段执行完毕后会进行执行阶段,在执行阶段中会对创建阶段定义的值进行赋值。
实战分析
我们用一个简单的例子来分析一下:
let a = 1
const b = 2
var c
function compute(n1,n2){
var n = 10
return n1 + n2 + n
}
c = compute(a,b)
- 首先进入创建阶段 全局环境的创建
var GlobalExectionContext = { // 全局执行上下文
LexicalEnvironment: { // 词法环境
EnvironmentRecor: {
a: uninitialized,
b: uninitialized,
compute:Function
},
OuterEnvironmentRecor: null // 全局记录时没有外部记录的
},
VariableEnvironment: { // 变量环境
EnvironmentRecord: {
c: undefined,// var创建的变量c
},
OuterEnvironmentRecor: null // 全局记录时没有外部记录的
}
}
- 函数环境的创建
var FunctionExectionContext = {
ThisBinding: Global Object, //由于函数是默认调用 this绑定同样是全局对象 LexicalEnvironment: { // 词法环境
EnvironmentRecord: {
Arguments: [
0: 1,
1: 2,
],
},
outer: GlobalEnvironment // 外部环境引入记录为Global
},
VariableEnvironment: {
g: undefined
},
outer: GlobalEnvironment // 外部环境引入记录为Global
}
}
- 创建完毕进入执行阶段,俺顺序执行
var GlobalExectionContext = { // 全局执行上下文
LexicalEnvironment: { // 词法环境
EnvironmentRecor: {
a: 1,
b: 2,
compute:Function
},
OuterEnvironmentRecor: null // 全局记录时没有外部记录的
},
VariableEnvironment: { // 变量环境
EnvironmentRecord: {
c: 13,//
},
OuterEnvironmentRecor: null // 全局记录时没有外部记录的
}
}
var FunctionExectionContext = {
ThisBinding: Global Object, //由于函数是默认调用 this绑定同样是全局对象 LexicalEnvironment: { // 词法环境
EnvironmentRecord: {
Arguments: [
0: 1,
1: 2,
],
},
outer: GlobalEnvironment // 外部环境引入记录为Global
},
VariableEnvironment: {
n: 10
},
OuterEnvironmentRecor: Global
}
}