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

JavaScript变量提升优先级:变量与函数谁先被提升?

理解JavaScript变量提升:拆解你的代码执行过程

别慌,我们把代码拆成编译阶段和执行阶段一步步分析,你就能搞懂第二个f()调用的结果了。

首先先贴出你的代码方便对照:

var alpha = 'alpha';
var beta = 'beta';
f(); // 你说输出beta?实际应该是alpha,后面会解释
var f = function f1() { console.log(beta); };
function f() { console.log(alpha); }
f(); // 你说输出alpha?实际应该是beta

第一步:编译阶段(变量提升的核心)

JavaScript引擎在执行代码前,会先扫描整个作用域处理所有声明,这就是变量提升的本质:

  • 所有var声明的变量会被提升到作用域顶部,初始值为undefined:比如alpha、beta、f都会被先声明,值都是undefined。
  • 函数声明会被完整提升(声明+定义),而且优先级比var变量高:所以同名的函数声明function f() { console.log(alpha); }会直接覆盖var f的初始undefined,此时f指向这个打印alpha的函数。

此时作用域的状态是:

  • alpha: undefined
  • beta: undefined
  • f: function f() { console.log(alpha); }

第二步:执行阶段(逐行跑代码)

现在开始逐行执行代码:

  1. var alpha = 'alpha'; → 给alpha赋值为'alpha'
  2. var beta = 'beta'; → 给beta赋值为'beta'
  3. f(); → 此时f还是编译阶段提升的那个函数,执行它会打印alpha的值,也就是'alpha'(这里你说输出beta,大概率是代码顺序写反了,或者你混淆了函数声明和表达式的提升)
  4. var f = function f1() { console.log(beta); }; → 这是变量赋值(声明已经在编译阶段处理完了),所以f被重新赋值为这个新的函数表达式
  5. function f() { console.log(alpha); } → 这是函数声明,编译阶段已经处理过了,执行阶段会直接跳过这一行,不会改变f的值
  6. f(); → 此时f已经被步骤4的赋值覆盖,执行这个新函数会打印beta的值,也就是'beta'

你的困惑点在哪里?

你可能误以为后面的函数声明function f()会在执行阶段重新覆盖f的值,但实际上函数声明只在编译阶段处理一次,执行阶段遇到函数声明会直接忽略。步骤4的赋值操作已经把f替换成了新的函数,所以第二个f()调用的是这个新函数,而不是最初的函数声明。

如果你的实际运行结果和这个分析不符,建议检查代码中函数声明和变量赋值的顺序是否搞反了~


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:44:50