函数声明可提升且能提前调用,匿名函数表达式不可提升、赋值后才可用;命名函数表达式的名字仅在内部有效,仍属表达式无提升。

函数声明和匿名函数表达式在 JavaScript 中看起来相似,但行为差异明显——关键不在“有没有名字”,而在“怎么出现”和“什么时候可用”。
函数声明:自带提升,可提前调用
函数声明是独立语句,形如 function foo() { ... }。它会在代码执行前被“提升”(hoisted)到当前作用域顶部,因此允许在声明之前调用:
-
合法且运行正常:
foo(); function foo() { console.log('hi'); } - 必须有函数名,这个名称在所在作用域中绑定为函数引用
- 不能出现在条件块、循环或 try/catch 内部(严格模式下会报语法错误)
匿名函数表达式:赋值时才生效,不可提前调用
匿名函数表达式本质是表达式,常写作 var fn = function() { ... };。它不是语句,而是把一个没有名字的函数作为值赋给变量:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
调用会报错:
fn(); var fn = function() { console.log('hi'); };—— 此时fn是undefined - 函数本身没有名字,
fn.name返回空字符串,调试时堆栈中显示anonymous - 可以出现在任意表达式上下文里,比如
if分支、对象属性、回调参数中
命名函数表达式:名字只在内部有效
虽然你问的是“匿名”,但常有人混淆命名函数表达式(如 var fn = function bar() { ... };)。需注意:
-
bar这个名字只在函数体内可用(用于递归或调试),外部无法访问 -
fn.name仍为"bar",但bar()在外部调用会报ReferenceError - 它仍是函数表达式,不具备提升特性,依然要等赋值执行后才可用
选择依据:看你要什么行为
不需要提前调用、强调模块化或动态创建?用匿名函数表达式。需要语义清晰、支持前置调用、定义主逻辑入口?优先函数声明。
- 工具函数、事件回调、IIFE 通常用表达式
- 顶层业务函数、构造逻辑、导出主接口常用声明
- TypeScript 或现代构建工具中,二者在类型推导和 tree-shaking 行为上也可能不同
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










