具名函数表达式(nfe)是安全递归的推荐方式,因其函数名仅在函数内部可见,支持自引用且不污染外层作用域;而函数声明会提升并泄漏名称,匿名函数表达式无法内部自引用。

具名函数表达式(Named Function Expression, NFE)是实现安全递归的推荐方式,它既避免了对 arguments.callee 的依赖(该属性已被严格模式禁用),又不会将函数名泄漏到外层作用域,从而保持封装性和解耦性。
为什么用具名函数表达式而非函数声明或匿名表达式
函数声明会提升(hoist)并污染当前作用域;纯匿名函数表达式无法在内部引用自身。而具名函数表达式中的名称仅在函数体内部可见,外部不可访问,天然支持自引用且不污染作用域。
正确写法:在函数体内通过名字调用自身
具名函数表达式的名称只在函数内部作用域有效,可在递归逻辑中直接使用:
const factorial = function fact(n) {
if (n console.log(factorial(5)); // 120
console.log(typeof fact); // undefined(外部无此变量)
确保解耦的关键细节
- 不要把具名函数赋给全局变量或模块顶层变量名以外的标识符(如
var fact = function fact() {...}是冗余且易混淆的) - 函数名应语义清晰(如
parseNode、deepClone),便于调试时堆栈追踪 - 若需多次复用,仍应将其赋值给一个有意义的常量(如
const traverseTree = function walk(node) {...}),名称walk仅用于内部递归 - 避免在函数体内修改外部变量,保持纯函数特性——递归逻辑与数据输入/输出解耦
常见误用及修复
❌ 错误:在非严格模式下依赖 arguments.callee —— 不可移植、不可读、被现代引擎标记为废弃
❌ 错误:用函数声明替代表达式 —— 名称 fact 会泄漏到外层作用域,破坏封装
✅ 正确:始终用 const fn = function name(...) { ... name(...); } 模式,名称仅作内部递归锚点











