前言
我们知道一个函数执行时,会创建一个执行上下文,而一个执行上下文的声明周期可以分为两个阶段:
- 创建阶段
在创建阶段,执行上下文会创建变量对象、生成作用域链、确定this的指向 - 代码执行阶段
创建完成之后,会执行代码,包括赋值语句、函数调用和其他语句
从这里我们就可以看出详细了解执行上下文极为重要,因为其中涉及到了变量对象,作用域链,this等很多人没有怎么弄明白,但是却极为重要的概念,它关系到我们能不能真正理解JavaScript。在后面的文章中我们会一一详细总结,这里我们先重点了解变量对象。
变量对象(Variable Object)
变量对象的生成规则如下:
- 根据形参建立当前上下文的参数,如果是函数则是函数所有的形参;没有实参,属性值默认为undefined
- 当前执行上下文中的函数声明,在变量对象中以key-value的形式存在;如果变量对象上已存在相同名称的属性,则覆盖
- 当前执行上下文中的变量声明,由名称和对应值(undefined)组成一个变量对象的属性创建,若已存在相同名称的属性,则忽略,防止覆盖上面两步生成的属性。
使用let
const
定义的变量会产生暂时性死区,即不允许变量定义之前使用变量。
根据这个规则,理解变量提升就变得十分简单了。
举个例子:
1 | // demo01 |
当执行到test()
时,函数test的执行上下文开始创建,以如下形式来表示:
1 | // 创建阶段 |
进入执行阶段,变量对象变成活动对象(activation object)。变量对象和活动对象是同一个对象,只是处于执行上下文不同的生命周期,只有位于执行栈顶部的执行上下文中的变量对
象才会变成活动对象。
1 | // 执行阶段 |
参考链接
三、变量对象
【进阶1-2期】JavaScript深入之执行上下文栈和变量对象