函数声明提升优先级最高,会完整提升函数名和函数体,var仅提升声明且值为undefined;同名时函数先绑定,后续var赋值可覆盖;let/const和函数表达式不享受该提升规则。

函数声明在提升阶段优先级最高,会完整提升(含函数体),而 var 变量只提升声明、不提升赋值;同名时函数先绑定,后续 var 赋值可覆盖它;let/const 和函数表达式不享受此提升规则。
函数声明比 var 声明更早“就位”
JavaScript 引擎在创建执行上下文时,先扫描并提升所有函数声明(function foo() {}),把函数名和整个函数体一起绑定到作用域中;之后才处理 var 声明,仅将变量名挂起,初始值为 undefined。
- 即使函数写在 var 后面,也能在代码顶部被调用
- console.log(foo) 放在 function foo() {} 之前,输出的是函数本身
- console.log(bar) 放在 var bar = ... 之前,输出 undefined
同名时函数胜出,但赋值仍有效
当函数声明与 var 声明同名,函数声明在预编译阶段先绑定;var 的声明部分被忽略(因标识符已存在),但赋值语句照常执行,会覆盖函数值。
- function a() { return 1; }; var a = 2; → 最终 a 是数字 2
- var a; function a() {} → a 仍是函数(var 声明无赋值,不覆盖)
- 多个同名函数声明时,后声明的覆盖先声明的,提升阶段即完成
函数表达式、let/const 不参与函数级提升
以 var fn = function() {} 或 const fn = () => {} 形式定义的,属于函数表达式,不享受函数声明的提升特权。
立即学习“Java免费学习笔记(深入)”;
- 它们只遵循对应变量声明规则:var 部分提升、值为 undefined;let/const 完全不提升,访问即报 ReferenceError
- function 关键字开头才是函数声明;const fn = function() {} 本质是 const 声明 + 函数表达式
- 箭头函数、class 声明、方法简写都不具备函数声明的提升能力
为什么这个优先级容易被忽略
表面看都是“提升”,但行为差异明显:函数声明提升带来可立即调用的能力,var 提升只带来 undefined,let/const 提升则根本不存在——只有暂时性死区。
- 混淆声明方式会导致运行时错误,比如在声明前调用 let 绑定的函数表达式
- 过度依赖提升可能掩盖逻辑问题,现代实践更倾向显式声明、避免跨行依赖
- ES6 后推荐用 const + 函数表达式或模块导出,意图清晰、不易出错


















