今天看到一个很有趣的内容:词法环境(理解中有些类似作用域)
在ES6中,用来定义标识符与函数和变量的关联关系。分为两部分:环境记录(environment record)和外部词法环境
环境记录:用来存储变量和函数声明的实际位置 外部词法环境引用:可以访问到的外部词法环境
词法环境可以分为两种:
1.全局环境,没有外部环境的词法环境,外部词法环境引用为null,有一个全局对象window,当前环境的this指向为window 2.函数环境,用户在函数定义的变量被存储在环境记录中,对外部环境引用可以是全局环境或者包含当前函数的外部环境(也代表this指向问题)
环境记录分为两种类型:
1.声明性环境记录 存储变量,函数,参数。一个函数环境包含了声明性环境记录 2.对象环境记录 用来定义在全局执行上下文中出现的变量和函数的关联,全局环境包含了对象环境记录
GlobalExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 标识符绑定在这里
outer: <null>
}
}
FunctionExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 标识符绑定在这里
outer: <Global or outer function environment reference>
}
}
变量环境 这也是一种词法环境,在ES6中主要分为LexicalEnvironment(用来存let和const声明)和VariableEnvironment(用来存var声明),
let a = 1
const b = 2
console.log(c)
var c = 3
词法环境绑定:
GlobalExectionContext = {
ThisBinding: <Global Object>,
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 标识符绑定在这里
a: < uninitialized >,
b: < uninitialized >,
multiply: < func >
}
outer: <null>
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 标识符绑定在这里
c: undefined,
}
outer: <null>
}
}
a和b的变量没有绑定任何内容,表示未初始化,但是c这个var变量在最初就绑定了undefined。 代码创建阶段,解析变量,var 变量会被置位undefined,而const let则未初始化。 变量提升由此而来,c变量你可以声明前访问不错,因为解析的时候会自动赋值undefined,而const let则不行