此问题旨在作为消除描述性术语“递归”或“递归”歧义的规范问题/答案。在适用的范围内,“碰巧引用自身的非终止过程”和“重复调度”。
在 JavaScript
的定义和区别是什么
- “递归”;
- “一个碰巧引用自身的非终止过程”;和
- “重复调度”
我经常看到当函数重复调用自身时使用术语“递归”,尽管 JavaScript
中“递归”的明确定义是什么? ?
我很少看到在描述函数模式时使用的术语“碰巧引用自身的非终止过程”或“重复调度”;通常,“递归”或“递归”用于描述一种模式,其中在函数调用体内,对开始该过程的原始函数进行函数调用。
什么时候“递归”不适用于特定的函数模式; “递归”、“碰巧引用自身的非终止过程”和“重复调度”之间的明确定义和区别是什么?
最佳答案
递归
I often see the term "recursion" used when a function repeated calls itself, though what is the unambiguous definition of "recursion" in JavaScript?
这个定义看起来不错,但是函数不必直接调用自身来递归,它的执行只需要导致它被再次调用。函数不直接调用自身的递归示例如下:调用 A();
会调用 B();
,而 B();
又会调用 C();
再次调用 A();
。
重复调度
像这样的函数使用重复调度:
function A ( foo ) {
var bar;
setTimeout( A, 0 );
console.log( 'hello' );
}
它不是递归的,因为 A 不会在同一调用堆栈上重复调用。当当前的调用堆栈完成时(这意味着“hello”将被记录)并且在事件循环中再次调用 A 之前没有其他任何事情,A 将被调用。除了同步代码和异步代码之间的区别之外,这里的重要区别在于,一次只有一份 foo
和 bar
副本,并且调用堆栈不是“t 不断增长,因此不会出现内存或超出最大调用堆栈大小的错误,而对于使用递归的版本,则会出现这种情况:
function A ( foo ) {
var bar;
A();
console.log( 'hello' );
}
在这种情况下,“hello”将永远不会被打印,因为 A
在到达日志语句之前调用自身。
引用自身的非终止过程
非终止过程只是一个无限循环。引用自身有点没有意义:
function A ( ) {
// Never terminates
while ( true ) {
// If A() is called here, or before
// the loop you have infinite
// recursion and a stack size error
}
// If, instead, A() is called here,
// you just have an infinite-loop,
// since this statement is never reached
}
关于recursion - "recursion"、 "a non-terminating procedure that happens to refer to itself"和 "repeated scheduling"之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41292992/