变量对象/变量提升

Posted 纸 飞机

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了变量对象/变量提升相关的知识,希望对你有一定的参考价值。

JS代码执行时要先创建执行上下文 (Execution Context),然后在上下文中执行代码。其中创建上下文阶段会生成与之 关联的变量对象(Variable Object),它的 作用是保存上下文中定义的变量声明与函 数声明。变量提升的实质就是变量对象的 生成,其生成规则如下:

全局上下文的变量对象 :

(GlobleObject, GO)

(1) 打开网页创建GO对象:GO{ }。

(2) 在全局中寻找函数声明作为GO属性。

(3) 在 全 局 中 寻 找 变 量 声 明 作 为 GO 的 属 性,并赋值undefined。若GO中存在同名 属性,则忽略继续查找,不做任何覆盖。

函数上下文的变量对象 :

(VariableObject, VO)

与GO的差别在于多一个参数分析。

(1) 创建上下文时即函数执行前一瞬间生成 一个变量对象VO: VO{}。

(2) 检 查 函 数 参 数 : 将 函 数 的 形 参 添 加 为 VO属性,默认值为undefined。接收函数 的 实 参 ( 如 有 传 参 ) , 并 覆 盖 原 值 undefined。

(3) 检查函数声明:将函数声明添加为VO 属性,若VO中存在同名的属性,则覆盖其 属性为该函数。

(4) 检查局部变量:若VO中不存在与该局 部变量同名的属性,则添加属性到V0并赋 值为undefined。若VO中已存在同名的属 性,则不做任何覆盖。 所以如果遇到同名属性,优先级是:函数声明〉函数参数〉局部变量声明

(5) 之后进入代码执行阶段,变量对象会被 激活成活动对象(Activation Object, AO ) ,这 时 候 对 象 上 的 各 种 属 性 才 能 被 访 问。此时会进行变量赋值,函数引用,以 及顺序执行其他代码。VO与AO是同一个对象的两个不同周期的叫法。

function fn (a) {

  var a = 11

  function a () {

     console.log('我优先级最高')

  }

  console.log(a)

}

fn(10) //11

讲解: 

1. 形参a传过来,VO对象创造属性 VO.a = undefinded。

2. 结合实参,VO.a = 10 。

3. 查找函数声明,a被赋值为一个函数体,即由a = 10 变为 a = Function。

4. 查找变量声明,它本应该在VO对象内创造a属性并赋值为undefinded,但a属性已经存在,不做改动。

5. 开始执行函数代码,遇到var a = 11这一句,a被赋值为11,即a = Function变为 a = 11。

以上是关于变量对象/变量提升的主要内容,如果未能解决你的问题,请参考以下文章

变量对象/变量提升

JavaScript之预编译与变量提升windowAOGOreturnif

在一些片段之间填充对象变量的最佳方法

作用域与变量提升

JavaScript错题记录变量定义提升this指针指向运算符优先级原型继承全局变量污染对象属性及原型属性优先级

关于JavaScript变量提升的理解