JavaScript变量提升

51 阅读2分钟

JavaScript代码是按照顺序运行的吗?

showName()
console.log(myname)
var myname = '掘金'
function showName(){
  console.log('函数showName被执行')
}

我们先来看下上图中的代码,会打印出什么结果?很明显这里有变量提升,showName方法可以正常执行,myname会打印出undefined。var关键字声明的变量可以拆分成 var myname = undefined 和 myname = '掘金'。在代码执行时,var myname = undefined会被提升到代码的顶部,也就是变量提升。var myname = '掘金'代码真实移动了位置吗?并没有,在代码执行前有代码编译这个步骤,代码编译时将变量声明放入内存中。

1.编译阶段

未命名文件 (5).png 从上图可以看出,输入一段js代码,编译之后会分为执行上下文和可执行代码两部分。执行上下文中有一个变量环境对象,该对象中保存了变量提升的变量myname和函数showName。此时的变量环境对象可以看成是下图。

VariableEnvironment:
    myname-->undefined,
    showName-->function:{
        console.log('函数showName被执行')
    }

2.执行阶段

经过上面的编译阶段,进入执行阶段。

  • 当执行到showName方法时,在变量环境对象找到showName方法,然后执行log;
  • 当执行到log myname变量时,在变量环境对象中找到myname值为undefined,打印出undefined;
  • 执行到myname重新赋值,修改变量环境对象;
VariableEnvironment:
    myname-->掘金,
    showName-->function:{
        console.log('函数showName被执行')
    }

代码中出现重复的变量或函数了怎么办?

function showName(){
  console.log('掘金001')
}
showName()
function showName(){
  console.log('掘金002')
}
showName()

上图代码中有两个showName函数,代码会打印出什么结果呢?让我们来分析一下:

  • 编译阶段,变量环境对象存了第一个showName函数,遇到第二个showName函数也覆盖了之前的showName函数。
  • 执行阶段,执行showName函数,找到变量环境对象中的showName(也就是第二个showName),打印出'掘金002'。
  • 综上所述,代码中如果定义了两个同名函数,最后一个函数才会生效。