函数声明会被提升到作用域顶部,可先调用后定义;函数表达式是赋值操作,必须先定义再使用,var仅变量名提升、let/const不提升,块内函数声明行为不统一,表达式支持iife而声明需转为表达式才能立即执行。

函数声明在代码执行前就被解析并提升到当前作用域顶部,所以能在定义之前调用;函数表达式只是变量赋值操作,只有执行到那一行时才真正创建函数,因此必须先定义再使用。
函数声明:预编译阶段就可用
JavaScript 引擎在进入执行阶段前,会先进行“预编译”(或称创建执行上下文),此时所有函数声明会被整体提升——包括函数名和函数体。这意味着:
- 即使调用语句写在 function 关键字之前,也能正常运行
- 提升范围是整个函数作用域或全局作用域
- 函数名在作用域内始终可访问,包括声明前的代码位置
函数表达式:执行到赋值行才生效
函数表达式本质是赋值语句,它的行为取决于所用的变量声明方式:
-
var 声明:仅变量名被提升,赋值(即函数创建)仍发生在原位置,调用会报
TypeError -
let/const 声明:变量声明不提升,提前访问直接抛
ReferenceError - 箭头函数也属于函数表达式,同样不提升
块级作用域中的表现差异
函数声明在块中(如 if、for)的行为不统一,尤其在旧环境里可能被意外提升到外部;而函数表达式严格遵循块级作用域规则:
- if 块内的
function demo() {}在非严格模式下可能泄漏到外层 - 同块内的
const demo = function() {}只在该块内有效,不会污染外部
立即执行场景的限制
函数表达式天然支持立即执行(IIFE),加括号即可:
(function() { console.log('run'); })();
函数声明不能直接 IIFE,否则语法错误;必须先转为表达式形式,比如加括号或取反:
(function() { console.log('ok'); })(); 或 !function() { console.log('ok'); }();











