问题描述
如果我可以使用命名的递归函数,那么应该有一种方法可以使用tco匿名递归函数。如果有办法,请解释下面的操作方法,这是我的递归函数和TCO函数。
If I can tco a named recursive function there should be a way to tco anonymous recursive function.If there is a way please explain how to do this below is my recursive function and TCO function.
function recursive(length, callback) {
tco((function (i, sum) {
var args = arguments;
if (i > length) {
console.log("break statement");
callback(sum)
return sum
} else {
return args.callee(i + 1, sum + i)
}
}))(0, 0)
}
function tco(f) {
var value;
var active = false;
var accumulated = [];
return function accumulator() {
accumulated.push(arguments);
if (!active) {
active = true;
while (accumulated.length) {
value = f.apply(this, accumulated.shift());
}
active = false;
return value;
}
}
}
推荐答案
尾部呼叫优化
ES6建议对尾部呼叫系统进行更改,即引擎优化。尾调用是指函数被调用为另一个函数中的最后一个语句,如下所示:
Tail Call Optimization
ES6 proposes changes to the tail-call system, an engine optimization. A tail-call is when a function is called as the last statement in another function, like this:
function doSomething() {
return doSomethingElse(); // tail call
}
ECMAScript 6寻求减小调用堆栈的大小某些尾部调用严格模式。通过此优化,而不是为尾调用创建新的堆栈帧,只要满足以下条件,就会清除并重用当前堆栈帧:
ECMAScript 6 seeks to reduce the size of the call stack for certain tail calls in strict mode. With this optimization, instead of creating a new stack frame for a tail call, the current stack frame is cleared and reused so long as the following conditions are met:
- 必须打开严格模式。
- 尾调用不需要访问当前堆栈帧中的变量(意味着函数不是一个闭包)。
- 尾部调用返回后,尾部调用函数没有进一步的工作要做。
- 尾部调用的结果作为函数值返回。
- strict mode must be turned on.
- The tail call does not require access to variables in the current stack frame (meaning the function is not a closure).
- The function making the tail call has no further work to do after the tail call returns.
- The result of the tail call is returned as the function value.
"use strict";
function doSomething() {
var num = 1,
func = () => num;
// not optimized - function is a closure
return func();
}
利用TCO优化:
考虑这个计算阶乘的函数:
Harness the TCO optimization:
Consider this function, which computes factorials:
"use strict";
function factorial(n) {
if (n <= 1) {
return 1;
} else {
// not optimized - must multiply after returning
return n * factorial(n - 1);
}
}
为了优化功能,您需要确保在最后一次函数调用之后不会发生乘法。
In order to optimize the function, you need to ensure that the multiplication doesn’t happen after the last function call.
"use strict";
function factorial(n, p = 1) {
if (n <= 1) {
return 1 * p;
} else {
let result = n * p;
// optimized
return factorial(n - 1, result);
}
}
来源: An 很棒的由Nicholas Zakas撰写,了解ECMAScript 6。
Source: An Awesome book by Nicholas Zakas, Understanding ECMAScript 6.
这篇关于如何在ES5中的递归匿名函数上应用TCO(尾调用优化)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!