函数声明会被提升至当前作用域顶部,仅声明被提升而非赋值,且优先级高于变量声明;同名时函数覆盖var变量声明,但与let/const同名会报错;块级内函数声明在严格模式下不提升,箭头函数、class等无此特性。

JavaScript 中函数声明会被提升到当前作用域顶部,但提升的只是声明,不包括赋值;而且函数声明提升优先级高于变量声明,同名时函数声明会覆盖变量声明。
函数声明提升只提升声明,不提升初始化
函数声明(function foo() {})在代码执行前就被解析并放入当前作用域的词法环境,因此可以在声明前调用。但注意:只有函数体被提升,内部的变量或闭包绑定仍按正常时序执行。
- 可以安全地在声明前调用函数,例如:foo(); function foo() { console.log('ok'); }
- 但如果函数内部引用了尚未声明的变量(如用 let 声明),运行时仍会报错,因为该变量处于“暂时性死区”
- 函数表达式(const foo = function() {})不会被提升,提前调用会报 ReferenceError
函数声明与变量声明同名时,函数优先
当函数声明和 var 变量声明使用相同标识符时,函数声明不仅提升,还会覆盖同名的变量声明(即使变量声明写在函数前面)。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- console.log(typeof a); // "function"
var a = 1;
function a() {} - 实际提升顺序等价于:function a() {};
var a;
a = 1; —— 所以 typeof a 是 function,但后续赋值会覆盖它 - 若换成 let/const 声明同名变量,则会直接报语法错误(重复声明),因为 let/const 不允许重复声明,且不参与函数提升竞争
嵌套作用域中,提升仅限于当前作用域
函数声明的提升不会跨作用域。块级作用域(如 if、for 或 {})内声明的函数,在严格模式下行为不同,非严格模式下可能被提升到函数作用域顶层,但这是非标准且不推荐的行为。
立即学习“Java免费学习笔记(深入)”;
- 在严格模式下:if (false) { function f() {} } console.log(f); // ReferenceError
- 非严格模式下某些引擎会将块内函数声明提升至外层函数作用域,但各浏览器实现不一致,应避免依赖
- 箭头函数、class 声明、模块顶层的函数都不具备函数声明那样的提升特性
提升发生在编译阶段,与执行顺序无关
提升不是代码“移动”,而是 JavaScript 引擎在进入作用域前,扫描并注册函数声明的过程。这个过程发生在执行上下文创建阶段,早于任何语句执行。
- 即使函数声明被包裹在永不执行的条件分支里(如 if (false) { function x() {} }),在非严格模式下仍可能被提升(但属历史遗留行为,ES6+ 已明确不鼓励)
- 真正可靠的做法是:把函数声明放在作用域顶部,或统一使用函数表达式 + 显式定义,避免依赖提升逻辑
- 现代开发中,借助 ESLint 规则(如 no-use-before-define)可主动拦截潜在问题

















