1. 语法差异
函数声明(Function Declaration)
function add(a, b) {
return a + b;
}
- 是语法级别的声明,函数名会被提升(Hoisting),可在声明前调用。
- 函数名是不可变的,无法通过 const/let 重新赋值。
函数表达式(Function Expression)通过 const 定义
const add = function(a, b) {
return a + b;
};
- 是变量赋值操作,函数本身是匿名函数(除非显式命名),变量名 add 被提升但初始值为 undefined。
- const 确保变量名不可重新声明,但函数引用可被覆盖(如 add = () => {} 会报错,但可通过 add = newFunc 重新赋值)。
2. 作用域与提升
特性 | 函数声明(function) | 函数表达式(const) |
提升 | 函数名和函数体均被提升 | 变量名被提升,但初始值为 undefined |
作用域 | 函数作用域(声明在块内时仍提升到函数顶部) | 块级作用域(受 const 限制) |
调试友好性 | 函数名在堆栈跟踪中可见 | 匿名函数默认显示为 anonymous,需显式命名(如 const add = function namedAdd() {}) |
3. 核心价值对比
函数声明(function)的优势
- 提升特性:无需关心函数调用顺序,适合复杂逻辑。
- 调试友好:函数名在堆栈跟踪中清晰可见。
- 递归支持:函数体内可直接引用自身名称(如 function factorial(n) { return n * factorial(n-1); })。
函数表达式(const)的优势
- 块级作用域:通过 const 限制变量作用域,避免全局污染。
- 灵活赋值:可动态赋值或通过参数传递函数(如 const add = getAddFunction();)。
- 与 ES6 语法兼容:可结合箭头函数(const add = (a, b) => a + b;),而 function 声明无法使用箭头语法。
4. 使用场景建议
- 优先选择 function 声明:
- 需要函数名在堆栈中可见(如调试)。
- 需要函数递归或内部引用自身。
- 代码逻辑依赖提升特性。
- 优先选择 const 表达式:
- 需要块级作用域(如 if/for 内部)。
- 需要与 ES6 语法(如箭头函数)结合。
- 需要更细粒度的变量控制(如模块导出或动态赋值)。
示例对比
// 场景1:函数声明的提升
console.log(add(1, 2)); // 输出 3(函数已提升)
function add(a, b) { return a + b; }
// 场景2:函数表达式的未初始化调用
console.log(add(1, 2)); // 报错:undefined 不是函数
const add = function(a, b) { return a + b; };
通过理解这些差异,开发者可以更灵活地选择语法,提升代码可维护性和性能。