笔记

92 阅读2分钟

今天看到一个很有趣的内容:词法环境(理解中有些类似作用域)

在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则不行