函数声明递归实现:移除arguments.callee且不依赖函数名的方法
移除函数声明递归中的
arguments.callee且不依赖函数名的方案 嘿,这个需求挺典型的!要解决这个问题,咱们可以借助Y组合子(Y Combinator)——这是函数式编程里实现匿名递归的经典工具,完美适配你“不用arguments.callee,也不依赖函数名”的要求。
核心问题拆解
你原来的代码用arguments.callee实现递归,但这个特性已经被ES5严格模式废弃;如果直接用函数名fib递归,又不符合“不依赖函数名”的限制。Y组合子的作用就是帮我们创建一个能自我引用的匿名函数,彻底绕开这两个问题。
具体改造后的代码
直接调整你给出的斐波那契函数声明:
function fib(n) { // 定义Y组合子 const Y = (fn) => (f => f(f))(f => fn((...args) => f(f)(...args))); // 把递归逻辑传给Y组合子,生成匿名递归函数并调用 return Y(self => num => num < 3 ? 1 : self(num - 1) + self(num - 2))(n); }
简单原理说明
- Y组合子通过闭包机制,让递归逻辑里的
self参数指向函数自身,完全不需要依赖外部的函数名fib; - 整个实现没有用到
arguments.callee,完全符合现代JS的标准规范; - 你还可以把Y组合子抽离出来复用,比如:
// 可复用的Y组合子 const Y = (fn) => (f => f(f))(f => fn((...args) => f(f)(...args))); // 函数声明里直接调用即可 function fib(n) { return Y(self => num => num < 3 ? 1 : self(num - 1) + self(num - 2))(n); }
这样不管后续你把函数名改成什么,内部的递归逻辑都不会受影响,完全满足你的需求~
内容的提问来源于stack exchange,提问作者mazza
相关产品推荐
相关产品推荐

