函数声明会被完全提升(包括函数名和函数体),而函数表达式只有变量声明部分被提升,赋值操作保留在原位置;let/const声明的函数表达式进入tdz,箭头函数无提升能力。

函数声明会被完全提升(包括函数名和函数体),而函数表达式只有变量声明部分被提升,赋值操作仍保留在原位置。
函数声明的提升行为
函数声明在代码执行前就完成整个定义的提升,因此可以在声明之前调用:
foo(); // 正常输出 "hello"
function foo() {
console.log("hello");
}
这是因为 JavaScript 引擎在预编译阶段已将 function foo() {...} 整体提升到当前作用域顶部。
函数表达式的提升行为
函数表达式本质是变量赋值,只有 var 声明被提升,函数本身不会被提前初始化:
bar(); // TypeError: bar is not a function
var bar = function() {
console.log("world");
};
- 变量 bar 被声明并初始化为 undefined
- 函数赋值语句仍在原位置执行,尚未运行
- 此时调用 bar() 相当于调用 undefined()
使用 let/const 声明函数表达式时的差异
用 let 或 const 定义函数表达式时,变量不会被提升,而是进入“暂时性死区”(TDZ):
baz(); // ReferenceError: Cannot access 'baz' before initialization
let baz = function() {
console.log("es6");
};
- 变量 baz 不会像 var 那样被初始化为 undefined
- 从块级作用域开始到声明语句执行前,访问该变量都会报错
- 这是更严格的提升限制,有助于避免隐式错误
箭头函数与提升的关系
箭头函数只能作为表达式使用,因此它和普通函数表达式一样,不具提升能力:
qux(); // ReferenceError(若用 let/const)或 TypeError(若用 var)
const qux = () => console.log("arrow");
- 无论是否使用 const,箭头函数都不会被提升
- 它没有函数名,无法像函数声明那样通过名称提前引用
- 必须在定义之后才能调用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











