You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

变量提升的工作原理?函数与变量提升的差异及代码执行疑问

变量提升的工作原理及函数、变量提升的区别

咱们先从变量提升的核心逻辑说起:JavaScript引擎在执行代码前,会先对当前作用域的代码做一次预编译处理——简单说就是把所有var声明的变量和函数声明,“提前”移动到当前作用域的最顶部。但要注意两个关键细节:

  • var变量只有声明被提升,赋值操作会留在原地,而且提升后的变量会被默认初始化为undefined。
  • 函数声明是整个函数(包括函数体)都被提升,所以在作用域内任何位置都能直接调用这个函数。

函数提升与变量提升的核心区别

  • 优先级不同:当作用域内出现同名的函数声明和var变量声明时,函数提升的优先级更高,会覆盖变量的声明(但如果变量有赋值操作,赋值会在执行阶段覆盖函数)。
  • 提升内容不同:函数提升是完整的函数体,变量提升只是声明,默认值为undefined。

两段代码的执行分析

第一段代码:返回function的原因

function scope() {
  return hosting;
  function hosting() {
    var hosting = '15';
  }
  var hosting = 12;
}
console.log(typeof scope())

在预编译阶段,JS引擎会完成两个操作:

  1. 把函数声明function hosting()完整提升到scope作用域的最顶部;
  2. 把var hosting的声明也提升,但因为函数提升优先级更高,此时hosting指向的是那个函数,变量声明被函数覆盖。

当代码执行到return hosting时,直接返回了被提升后的函数,所以typeof结果是function。后面的变量赋值var hosting = 12根本没机会执行,因为return已经跳出了函数。

第二段代码:为什么不返回number

function scope() {
  return hosting;
  var hosting = 12;
}
console.log(typeof scope())

预编译阶段,只有var hosting的声明被提升到作用域顶部,此时hosting被初始化为undefined。

执行代码时,先遇到return hosting,此时hosting还没执行到赋值语句var hosting = 12(赋值在return后面,完全没机会运行),所以返回的是undefined,typeof结果自然是undefined,而不是number。

你提到用let可以避免这种情况,是因为let声明的变量不存在变量提升,而且存在“暂时性死区”——在声明前访问let变量会直接抛出错误,从根源上避免了这种混淆。

内容的提问来源于stack exchange,提问作者Selva Ganapathi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 21:52:31