具名函数表达式是实现函数表达式递归的推荐方式,通过在function后声明内部名称(如fact),仅在函数体内可见,可安全递归调用且不污染外层作用域。

JavaScript 中函数表达式本身没有名字,无法像函数声明那样直接通过名称调用自身。要实现递归,关键在于让函数能“引用自己”——常用方式是借助 arguments.callee(已废弃)、命名函数表达式,或更现代、推荐的「具名函数表达式」(Named Function Expression)。
使用具名函数表达式(推荐)
给函数表达式起一个内部名称,该名称仅在函数体内可见,可用于递归调用,且语义清晰、兼容性好、符合现代规范。
- 语法:在
function关键字后紧跟一个标识符(如factorial),它不是变量名,不污染外层作用域 - 函数体内部可通过该名称安全调用自身
- 避免依赖已弃用的
arguments.callee
示例:计算阶乘
const factorial = function fact(n) {
if (n <= 1) return 1;
return n * fact(n - 1); // 使用内部名 `fact` 递归
};调用 factorial(5) 正常返回 120;即使把 factorial 赋值给其他变量或设为 null,函数内部仍可通过 fact 自引用。
立即学习“Java免费学习笔记(深入)”;
用参数传递自身(适用于高阶场景)
将函数作为参数传给自己,显式建立递归链。适合需要动态构造或与柯里化、组合等配合的场景。
- 函数第一个参数约定为“自身”,后续参数为实际业务参数
- 调用时需手动把函数传入自身,稍显冗余但完全可控
示例:
const factorial = function(self, n) {
if (n <= 1) return 1;
return n * self(self, n - 1);
};
// 使用时需传入自身
console.log(factorial(factorial, 5)); // 120也可封装成更易用的形式,比如立即执行并返回闭包:
const factorial = (function makeFactorial() {
return function f(n) {
if (n <= 1) return 1;
return n * f(n - 1);
};
})();避免使用 arguments.callee(不推荐)
arguments.callee 曾用于匿名函数中指向当前函数,但ES5 严格模式下禁用,且影响引擎优化、降低可读性,已属过时写法。
❌ 不安全示例(严格模式报错):
const factorial = function(n) {
"use strict";
if (n <= 1) return 1;
return n * arguments.callee(n - 1); // TypeError!
};箭头函数不能直接递归
箭头函数没有自己的 arguments 和 this,也没有函数名绑定机制,无法自然实现递归。
- 试图用外部变量名调用:一旦变量被重新赋值或置为
null,就会出错 - 若真需用箭头函数递归,必须配合具名函数表达式或外部命名函数
✅ 可行写法(借助外部命名函数):
const factorial = function fact(n) {
return n <= 1 ? 1 : n * fact(n - 1);
};
const compute = (n) => factorial(n); // 箭头函数只是转发不复杂但容易忽略:递归函数表达式的命名是局部的、安全的,也是最贴近直觉和工程实践的方式。优先选具名函数表达式,明确意图,兼顾可读性与健壮性。


















