js中的重要概念
在当前函数中,要寻找到变量的值是从哪里来的,就首先会从当前执行上下文中查找,如果没有找到,则会去作用域链中查找。这里需要注意的是,作用域链本身就是存在于函数对象中的一个属性 [[Scopes]],因此不是一层一层的往上查找「这里经常理解有误」,该属性是在代码预解析阶段就已经确认好的。
作用域:作用域是规定变量与函数可访问范围的一套规则。
作用域的范围信息,是在预解析阶段就已经确定的
执行上下文:执行上下文包含了跟踪对应可执行代码执行进度所需要的所有状态,每个执行上下文中都有特定的实体对象用于记录这些特定状态。
函数调用栈:管理所有的执行上下文
运行时上下文:只能有一个,且处于栈顶。当代码执行过程中,有新的函数调用,新的执行上下文会被创建,入栈,并且成为新的运行时上下文
完整的作用域链:
都具备一个属性 [[Scopes]],该属性中存储了当前函数可访问的所有变量对象
- Global 全局对象:不会做任何优化,会包含全局对象中的所有属性与方法
- Script 对象:在全局环境下,由 let 和 const 声明的变量对象
- Closure 对象:我们讨论比较多的闭包对象,嵌套函数生成,仅会保存当前作用域能够访问的变量属性
- Local 对象:以上的几种变量对象,都会存在于函数的 [[Scopes]]属性之中,因为他们都能够在函数解析时确认,而 Local 对象则不行,需要在函数的执行过程中才能确定,并且在执行过程中,该对象中的属性是随时会发生变化的,该对象除了会存储当前函数上下文中所有的变量与函数声明,还会额外记录 this 的指向。
Local: 活动对象
由 函数参数,var 声明的变量,let/const 声明的变量,function 声明的变量,class 声明的变量,this 指向等共同组成。
仅仅只有处于栈顶的执行上下文,才会生成 Local 对象。并且 Local 对象的具体内容会在执行上下文的生命周期中不断变化。也就意味着,在执行上下文的创建阶段,只有函数参数、function 声明的变量、this 指向 能够明确具体的值,其他变量的初始值都为 undefined,然后在代码执行过程中逐步明确赋值。