Javascript 是否考虑任何自引用函数';递归';?

Javascript 是否考虑任何自引用函数';递归';?,javascript,recursion,Javascript,Recursion,关于JavaScript,我可以看到编写自引用函数的两种不同方式: 类似于分而治之的算法,如阶乘或合并排序,其中的值通过不断减小的样本大小递归计算: 通过自调用函数进行循环(当循环包含异步执行的代码(例如网络请求)但循环迭代需要序列化时,我发现这很有用) var结果=”; (函数doLoop(i){ 如果(i

关于JavaScript,我可以看到编写自引用函数的两种不同方式:

类似于分而治之的算法,如阶乘或合并排序,其中的值通过不断减小的样本大小递归计算:

通过自调用函数进行循环(当循环包含异步执行的代码(例如网络请求)但循环迭代需要序列化时,我发现这很有用)

var结果=”;
(函数doLoop(i){
如果(i<10){
i++;
请求('http://...,函数(err、res、body){
结果+=身体;
多卢普(i);
});
};
})(0);
在JavaScript中,当通过递归循环时,每个函数调用都会建立一个新的执行上下文,并且(在我看来)与调用不同函数的情况没有任何不同


这仍然被认为是递归吗?

我想在你的第二个例子中,你的意思是

function doLoop() {
   if (hasAsyncWork)
      doAsyncWork({callback: doLoop})
}
因此,函数将自己安排在以后某个时间运行,而不是直接调用自己。这种模式在JavaScript中使用很多,并且有很多变化,例如考虑:

function fun() {
   do something
   setTimeout(fun, 100)
}

甚至

async function fun(jobs) {
  if (jobs.length)
     await fun(jobs.slice(1))
}
从技术上讲,这不是递归,至少在传统意义上是这样

这仍然被认为是递归吗

归根结底,这更多的是一个命名和意见的问题,而不是一个纯粹的技术问题。但是,请考虑:
function A(num)
{
    if (num < 3) B(num);
}

function B(num)
{
    A(num - 1);
}
函数A(num)
{
如果(num<3)B(num);
}
函数B(num)
{
A(num-1);
}
也一直被认为是递归;
A
B
都不直接调用它们自己,但在整个调用链中存在递归。同样地,
A
B
都是递归的,因为
A
仍然导致调用
A
,同样地,
B

因此,您的示例与此类似,虽然
doLoop
不调用
doLoop
,但它确实导致调用
doLoop


有些人反对调用这种递归的地方是,
doLoop
不会是以前的
doLoop
调用链的一部分,或者可能不会(可以编写不清楚是否立即调用
doLoop
的版本)。但是,当考虑如何实现语言时(例如,是否存在允许递归的调用堆栈或其他机制),递归的更具体定义比它们的使用方式更有用

也许与georg相反,我认为georg和您的异步示例实际上都是传统意义上的递归示例。让我们看看维基百科中关于重复关系的定义:

...an equation that recursively defines a sequence or 
multidimensional array of values, once one or more
initial terms are given: each further term of the sequence
or array is defined as a function of the preceding terms.

需要注意的是,异步调用是否定义了一系列值(抽象地考虑“值”),每一个值都源自前一个术语。生成是延迟的还是有条件的似乎与我无关。

在这些代码位中尝试一些大的数字(大约60000)-您是否会遇到类似
InternalError:too more recursion
?好吧,这就是递归:pI仍在试图理解两种方法之间的区别…“我可以看到两种不同的编写自引用函数的方法”——相反。您确定了两种可以使用递归函数实现的编程技术。递归函数也可以用于其他用途。这些编程技术并没有以任何方式定义它们的存在。上述编程技术也可以在不使用递归函数的情况下实现;参见经典的
偶数
/
奇数
示例–自引用函数也可以生成非递归(迭代)过程;将您的
factorial
与使用a)的实现进行比较,这正是我的意思(我改变了我的问题以反映这一点)。如果不是递归的话,有没有专门的术语来描述它呢?@ZachSmith:我不知道这个用例有什么公认的术语,但是它太普遍了,以至于它确实应该有一个名字,那么“异步”呢是的,在“哲学”的意义上,递归是指它自身的一切,所以我们可以谈论一个递归过程,它自身分叉,或者递归类型。然而,从狭义上讲,我倾向于将递归函数视为在同一堆栈内运行(并导致其溢出;)的函数,而异步函数则在不同的堆栈上运行。
async function fun(jobs) {
  if (jobs.length)
     await fun(jobs.slice(1))
}
function A(num)
{
    if (num < 3) B(num);
}

function B(num)
{
    A(num - 1);
}
...an equation that recursively defines a sequence or 
multidimensional array of values, once one or more
initial terms are given: each further term of the sequence
or array is defined as a function of the preceding terms.