深入理解 JS 中的变量提升

首先来看一段代码,分析一下输出结果:
从上面的代码可以看出,foo()
在未定义时就进行了调用, 输出了 foo,console.log(bar)
在 bar 声明与赋值之前进行了调用,输出了 undefined
, 而 console.log(baz)
访问了一个代码中从未定义的变量,代码报错。
因此,我们可以看出以上 JS 代码并不是按照编写的顺序执行的,而是存在一种机制,似乎是函数和变量的声明被提前了? 是的,没错,这种看起来像是声明被提前的现象就是变量提升。
变量提升
详细来说,变量提升就是指 JS 在执行的过程中,JS 引擎会把变量及函数的声明部分提升到代码开头的行为,变量被提升后,会给变量设置默认值 undefined。
如上面代码中的 var bar = 'bar'
,变量提升后会分为声明和赋值两部分, 即:
为什么需要变量提升
那么,为什么要变量提升呢?因为 JS 代码需要先编译,再执行,经过编译后会生成执行上下文和可执行代码。
执行上下文就是 JS 执行一段代码时的运行环境,例如调用一个函数时,需要确定该函数所用到的变量、函数等。并且执行上下文中存在一个变量对象,而该对象中就保存了变量提升的内容。
伪代码如下:
那么可执行代码又是什么呢?JS 引擎生成变量对象后会把剩余的代码编译为字节码作为可执行代码,伪代码描述就是:
那么可执行代码执行时,按照顺序一行一行的执行,当遇到变量访问或者函数调用时会到变量对象中查找,以上面代码为例 foo()
输出了 foo
,console.log(bar)
输出了 undefined
,而 bar = 'bar'
进行了赋值操作,会覆盖掉 undefined
,如果再次访问 bar,那么输出就是 bar
了,最后由于 console.log(baz)
在变量对象中并未找到 baz
的定义,因此会抛出异常。
OK,以上就是关于变量提升的介绍。
Photo by KAL VISUALS on Unsplash
版权声明: 本文为 InfoQ 作者【Verlime】的原创文章。
原文链接:【http://xie.infoq.cn/article/9877d2e8b12a1cd4d4b39948b】。文章转载请联系作者。
评论