[ 面试系列 ] - 七:来看看这个变量提升?

874 阅读2分钟

系列文章

说在前面的

本来今天原计划是继续更新 CSS 相关的面试题,结果在中午水群的时候,有小伙伴发来一道题:

img-01

乍一看,这不是变量提升嘛,于是盲猜答案:7、7。

当然,答案毫无意外的错了,最终结果是:

img-02

这个 7 没什么疑问,但这个 3 就有点耐人寻味了......于是今天的文章就变成了这个。

分析

要弄明白这个问题,我们先来模拟一下变量提升。

忽略掉会影响到我们的代码,这段代码应该长这样:

{
  function a({}
}

而在浏览器编译它的时候,应该是这样的(参考):

var a₀ = undefined;
{
  let a₁ = function a({};
  a₀ = a₁;
}

(ps:在下英语实在太挫,就不全篇翻译了,有能力的小伙伴可以自行查看文档)

那么这里,我们可以用以下伪代码来分析这段流程:

var a₀ = undefined;
{
  let a₁ = function a({};
  a₁ = 3;
  a₀ = a₁;
  a₁ = 7;
  console.log(a₁);
}
console.log(a₀);

上面代码是怎么回事呢?

  • 首先这里有两个都叫做 a 的变量,一个是全局变量 a₀,一个是块作用于内的变量 a₁
  • 函数的变量提升让 let a₁ = function a() {} 提升到了块的顶部,但是赋值依然在后面
  • a₀ = a₁ 这一步实际上是执行到了函数定义的那一句 function a() {},而结果是内部的 a₁ 覆盖了外部的 a₀,所以 a₀ = 3 了
  • 后面的就不用解释了

事实上,根据上面的分析,即使没有外界的 var a,输出应该也是一样的:

img-03

参考