函数表达式不引发函数名重复问题,因其本质是将函数作为值赋给变量,无函数提升且仅影响变量绑定;而函数声明会提升并导致同名覆盖或重复声明报错。

函数表达式本身不产生函数名重复问题,因为它本质上是把函数当作值来赋给变量,而不是“声明”一个具名函数。关键在于:函数表达式没有函数提升(hoisting)行为,也不会触发同名覆盖逻辑,它只影响变量绑定。
函数表达式与函数名重复的关系
函数表达式写法如:
const foo = function() { console.log("first"); };
const foo = function() { console.log("second"); }; // ✅ 合法(ES6+ 严格模式下仍允许重定义 const?注意:实际会报错)但更常见且安全的是用 let 或重新赋值变量:
let foo = function() { console.log("first"); };
foo = function() { console.log("second"); }; // ✅ 正确:只是变量重新赋值这种写法不会引发“函数名重复定义”的错误,因为:
- 它不是函数声明(
function foo(){}),不参与作用域内函数名的绑定竞争; - 变量
foo是一个普通标识符,后续赋值只是改变其指向的函数对象; - 没有“覆盖函数声明”的语义冲突,只有内存引用变更。
如何避免混淆和潜在错误
-
不要混用函数声明和函数表达式定义同名标识符
function bar() { console.log(1); } const bar = function() { console.log(2); }; // ❌ 在同一作用域会报错:Identifier 'bar' has already been declared这里冲突源于
bar已被函数声明占据,再用const bar属于重复声明,不是函数重名问题,而是变量重复声明。 -
用不同变量名区分逻辑职责
const validateEmail = function(email) { /* ... */ }; const validatePhone = function(phone) { /* ... */ };比起反复复用同一个变量名,清晰命名更能避免维护混乱。
-
需要保留旧函数时,显式保存引用
let handler = function() { console.log("v1"); }; const oldHandler = handler; // 保存原函数 handler = function() { console.log("v2"); }; oldHandler(); // 输出 "v1"
和函数声明的关键区别
| 特性 | 函数声明(function foo(){}) |
函数表达式(const foo = function(){}) |
|---|---|---|
| 是否提升 | 是(整个函数体提升) | 否(仅变量声明提升,赋值不提升) |
| 同名重复定义后果 | 后者覆盖前者(JS中) | 若用 const/let 重复声明,直接报错;若用 var 或重新赋值,只是替换值 |
| 是否可被“覆盖调用” | 是,调用 foo() 总是执行最后声明的那个 |
是,调用 foo() 执行当前绑定的函数 |
不复杂但容易忽略

















