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

JavaScript Hoisting内存创建阶段提升规则与代码形态疑问

你梳理的提升后结构不正确,问题出在你把var foo = 3的赋值逻辑也直接删掉了,实际上只有var foo的声明部分会被忽略,赋值操作会保留在原位置等待执行。

先明确JS提升的核心规则:

  • 提升仅处理「声明」逻辑,所有赋值操作都会留在原代码的位置,在执行阶段按顺序运行
  • 同一作用域内,函数声明的提升优先级高于var变量声明:如果同名标识符已经被函数声明注册,后续的同名var声明会直接被跳过,不会覆盖已有的标识符绑定
  • 同一作用域内的同名函数声明,后出现的会覆盖先出现的绑定

你给出的代码完整处理流程

1. 内存创建(提升)阶段处理逻辑

按代码顺序扫描所有声明:

  1. 扫描到第一个function foo()声明,在作用域中注册标识符foo,值为返回1的函数
  2. 扫描到第二个function foo()声明,覆盖已有的foo绑定,此时foo的值为返回2的函数
  3. 扫描到var foo声明,发现foo已经在作用域中存在,该声明直接被忽略,不做任何处理

2. 执行阶段逻辑

按原代码的顺序执行剩下的逻辑,已经处理过的声明不会重复执行:

  1. 执行console.log(foo),此时foo还是提升阶段绑定的返回2的函数,因此输出对应结果
  2. 跳过两个已经处理过的函数声明
  3. 执行var foo = 3剩下的赋值逻辑foo = 3,此时foo的值才会被修改为3,但这一步在打印操作之后,不会影响打印结果

正确的等效提升后代码

// 提升阶段完成的声明处理
function foo() {
    return 1;
}
// 后声明的同名函数覆盖前一个绑定
function foo() {
    return 2;
}
// var foo 的声明部分因重复被忽略,仅剩余赋值操作留在原位置

// 执行阶段按原顺序运行
console.log(foo);     // 输出为:foo() { return 2; }

// 函数声明已在提升阶段处理,执行时无实际操作

foo = 3;

关于你的疑问:你认为“这段代码中并没有重复的var声明”是对的,但这里的“重复声明”指的是标识符foo已经通过函数声明完成了注册,不属于var声明之间的重复,只要是同一作用域内同名的声明,函数声明优先级更高,var的声明就会被跳过,仅保留赋值逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 23:39:01