JavaScript 变量提升与函数提升

理解函数声明和变量声明的提升顺序

问题

下面代码会输出什么?

foo();
var foo;
function foo(){
  console.log(1);
}
foo = function(){
  console.log(2);
}

解答

答案是:1

根据 JavaScript 的提升规则,函数声明会优先于变量声明被提升。上述代码在执行时会被解析成以下形式:

function foo(){
  console.log(1);
}
var foo; // 变量声明被提升,但不会覆盖已存在的函数

foo(); // 调用函数,输出 1
foo = function(){
  console.log(2);
}

执行过程:

  1. 函数 foo 的声明被提升到作用域顶部
  2. 变量 foo 的声明被提升,但因为同名函数已存在,不会改变 foo 的值
  3. 执行 foo(),此时 foo 是函数声明,输出 1
  4. 之后 foo 被重新赋值为新的函数表达式(输出 2),但这行代码在调用之后,不影响输出结果

关键点

  • 函数声明的提升优先级高于变量声明
  • 变量声明提升时,如果已存在同名函数,不会覆盖该函数
  • 函数表达式的赋值不会被提升,只有声明部分会提升
  • 代码执行顺序:先提升函数声明,再提升变量声明,最后按顺序执行代码