JavaScript函数调用子表达式可以是尾部调用吗?
考虑以下返回语句:JavaScript函数调用子表达式可以是尾部调用吗?,javascript,tail-recursion,tail-call-optimization,Javascript,Tail Recursion,Tail Call Optimization,考虑以下返回语句: 返回f()| g(); 调用f()显然不是尾部调用,因为如果f()为falsy,函数实际上不会返回 那么g()部分呢,这是尾部调用吗?或者我必须这样重写它: const temp=f(); 如果(温度)返回温度;else返回g(); 试试看 由于某种原因,我在睡眠剥夺状态下没有想到:D 函数f(){ 返回Math.random()>1 | | f(); } f() Node说RangeError:超过了最大调用堆栈大小,Firefox说InternalError:递归太
返回f()| g();
调用f()
显然不是尾部调用,因为如果f()
为falsy,函数实际上不会返回
那么g()
部分呢,这是尾部调用吗?或者我必须这样重写它:
const temp=f();
如果(温度)返回温度;else返回g();
试试看
由于某种原因,我在睡眠剥夺状态下没有想到:D
函数f(){
返回Math.random()>1 | | f();
}
f()
Node说
RangeError:超过了最大调用堆栈大小
,Firefox说InternalError:递归太多
是的,但在实践中没有帮助
根据说明,g()
处于尾部位置:
LogicalORExpression:LogicalORExpression | | LogicalDexpression
返回带有参数调用的LogicalANDExpression的HasCallInTailPosition
然而,大多数浏览器的尾部调用消除,Chromium团队并没有对此进行研究,因此无论您如何编写尾部调用,在实践中都不能依赖尾部调用消除。试试看?“我必须……”这在实践中并不重要。只有Safari真正支持尾部调用优化,不管标准怎么说。JS编码人员不必担心实现细节,因为实现细节经常会发生变化;这里的实际问题是什么?@dandavis:这对尾部调用消除很重要。@dandavis:尾部调用消除允许没有尾部调用消除就无法工作的程序设计。这不是一个实现细节。那是因为那些引擎根本不支持尾部调用消除。@user2357112supportsMonica,即使ES6强制要求它?TILno,
Math.random()永远不会返回>1
-始终为false,因此调用f()
forever@RandyCasburn我故意为这个实验选择了一个总是错误的条件。通过尾部调用优化,无限递归不会破坏堆栈,而是永远循环。啊,当然,得到了。@user2357112supportsMonica-说了些什么:-)