怎么在JavaScript中利用递归调用匿名函数

  介绍

怎么在JavaScript中利用递归调用匿名函数?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

以一个简单的阶乘计算为例:

function 阶乘(n), {,   if 才能;(n  & lt;=, 1), {   ,,,return  1;   ,,},{else    ,,,return  n  *,阶乘(n - 1);   ,,}   }

我们可以看的出,递归就是在函数内部调用对自身的调用。那么问题来了,我们知道在Javascript中,有一类函数叫做匿名函数,没有名称,怎么调用呢?当然你可以说,可以把匿名函数赋值给一个常量:

const  factorial =,函数(n) {,   ,,if  (n  & lt;=, 1), {   ,,,return  1;   ,,},{else    ,,,return  n  *,阶乘(n - 1);   ,,}   }

这当然是可以的。但是对于一些像,函数编写时并不知道自己将要赋值给一个明确的变量的情况时,就会遇到麻烦了。如:

(函数(f) {   f(10)才能;   })(函数(n) {   ,,if  (n  & lt;=, 1), {   ,,,return  1;   ,,},{else    ,,,return  n  *,阶乘(n - 1);//太依赖于上下文变量名   ,,}   })//Uncaught  ReferenceError:, factorial  is  not 定义(…)

那么存不存在一种完全不需要这种给予准确函数名(函数引用变量名)的方式呢?

<代码> arguments.callee

我们知道在任何一个函数内部,都可以访问到一个叫做参数的变量。

<代码>(函数(){console.dir(参数)})(1、2)

屏幕快照2016-09-18下午10.53.58

打印出这个参数变量的细节,可以看出他是争论的一个实例,而且从数据结构上来讲,他是一个类数组。他除了类数组的元素成员和长度属性外,还有一个被方法。那么这个被方法是做什么的呢?我们来看下MDN

被是参数对象的属性。在该函数的函数体内,它可以指向当前正在执行的函数。当函数是匿名函数时,这是很有用的,比如没有名字的函数表达式(也被叫做“匿名函数”)。

哈哈,很明显这就是我们想要的。接下来就是:

(函数(f) {   console.log才能(f (10));   })(函数(n) {   ,,if  (n  & lt;=, 1), {   ,,,return  1;   ,,},{else    ,,,return  n  *, arguments.callee (n - 1);   ,,}   })//输出:,3628800

但是还有一个问题,中数的文档里明确指出

警告:在ECMAScript第五版(ES5)的严格模式中禁止使用arguments.callee ()。

哎呀,原来在ES5的使用严格;中不给用啊,那么在ES6中,我们换个ES6函数写的箭头写看:

((f),=祝辞,console.log (f (10))) (   (n),才能=祝辞,n  & lt;=, 1 ?, 1:, arguments.callee (n - 1))//Uncaught  ReferenceError:, arguments  is  not 定义(…)

有一定ES6基础的同学,估计老早就想说了,箭头函数就是个简写形式的函数表达式,并且它拥有词法作用域的值(即不会新产生自己作用域下的,参数,超级和新的。目标等对象),且都是匿名的。

那怎么办呢?嘿嘿,我们需要借助一点FP的思想了。

<强> Y组合子

关于Y Combinator的文章可谓数不胜数,这个由师从希尔伯特的著名逻辑学家Haskell B。咖喱(Haskell语言就是以他命名的,而函数式编程语言里面的咖喱手法也是以他命名)”发明”出来的组合算子(Haskell是研究组合逻辑(组合逻辑)的)仿佛有种神奇的魔力,它能够算出给定λ表达式(函数)的不动点,从而使得递归成为可能。

这里需要告知一个概念<强>不动点组合子:

不动点组合子(英语:定点选择符,或不动点算子)是计算其他函数的一个不动点的高阶函数。

函数f的不动点是一个值x使得f (x)=x,例如,0和1是函数f (x)=x ^ 2的不动点,因为0 ^ 2=0而1 ^ 2=1。鉴于一阶函数(在简单值比如整数上的函数)的不动点是个一阶值,高阶函数f的不动点是另一个函数g使得f (g)=g。那么,不动点算子是任何函数修正使得对于任何函数f都有

f(修复(f))=修复(f)。不动点组合子允许定义匿名的递归函数。它们可以用非递归的λ抽象来定义。

在无类型λ演算中众所周知的(可能是最简单的)不动点组合子叫做Y组合子。

接下来,我们通过一定的演算推到下这个Y组合子。

//,首先我们定义这样一个可以用作求阶乘的递归函数   const  fact =, (n),=祝辞,n<=1 ? 1: n (n - 1) *事实,   console.log(事实(5)),//120//,既然不让这个函数有名字,我们就先给这个递归方法一个叫做自我的代号//,首先是一个接受这个递归函数作为参数的一个高阶函数   const  fact_gen =,(自我),=祝辞,(n),=祝辞,n

怎么在JavaScript中利用递归调用匿名函数