函数声明有名字、可提升,能提前调用;匿名函数实为函数表达式,无名、不提升,需赋值或括号包裹才能使用;命名函数表达式兼顾二者特性。

函数声明和匿名函数声明在 JavaScript 中看起来相似,但本质不同:前者是独立语句,有名字、可提升;后者是表达式的一部分,无名、不可提前调用。
核心区别在于“有没有名字”和“能不能提前用”
函数声明必须带函数名,例如 function sayHi() { }。它会被 JavaScript 引擎自动提升(hoist)到作用域顶部,所以可以在声明前调用。
匿名函数声明本身不合法——function() { } 单独写会报语法错误。真正能用的,是把它作为值赋给变量或参数,比如 const sayHi = function() { };,这时它才成为函数表达式,而“匿名”仅指函数自身没有 name 属性。
函数声明的特点
- 语法形式固定:
function 名称(参数) { 函数体 } - 自动提升:声明前就能调用,引擎先扫描并注册所有函数声明
- 函数名可见且可用于递归或调试,
sayHi.name返回"sayHi" - 不能紧跟括号立即执行,
function foo(){}()不会调用,只解析函数
匿名函数(实际是函数表达式)的特点
- 必须出现在表达式位置:赋值给变量、传入参数、放在括号里等
- 不会提升:必须定义后才能调用,否则报
TypeError: xxx is not a function - 函数本身无名:
(function(){})().name是空字符串,但可被变量名间接引用 - 支持立即执行:
(function(){ console.log('run'); })();或!function(){ }();
命名函数表达式是个折中方案
你也可以写 const sayHi = function realName() { }; ——外层是变量名,内层是函数自己的名字。这个 realName 在函数内部可用(比如递归),外部不可见,sayHi.name 仍返回 "realName"。
说到底,是否具名、是否提升、是否可立即执行,这三点决定了该用哪一种写法。业务逻辑主入口常用函数声明,回调、闭包、模块封装多用函数表达式。











