[英]How would I write a recursive function that sums an array of numbers that uses tail call optimization (TCO)?
[英]How do i apply TCO(Tail Call Optimiztion) on recursive anonymous Function in ES5
如果我可以 tco 命名遞歸函數,那么應該有一種方法可以 tco 匿名遞歸函數。如果有辦法請解釋如何做到這一點,下面是我的遞歸函數和 TCO 函數。
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 提出了對尾調用系統的更改,這是一項引擎優化。 尾調用是指一個函數作為另一個函數中的最后一條語句被調用,如下所示:
function doSomething() {
return doSomethingElse(); // tail call
}
ECMAScript 6 試圖在嚴格模式下減少某些尾調用的調用堆棧的大小。 通過這種優化,只要滿足以下條件,就不會為尾調用創建新的堆棧幀,而是清除並重用當前堆棧幀:
也許最難避免的情況是使用閉包。 因為閉包可以訪問包含范圍內的變量,所以可能會關閉尾調用優化。 例如:
"use strict";
function doSomething() {
var num = 1,
func = () => num;
// not optimized - function is a closure
return func();
}
考慮這個計算階乘的函數:
"use strict";
function factorial(n) {
if (n <= 1) {
return 1;
} else {
// not optimized - must multiply after returning
return n * factorial(n - 1);
}
}
為了優化函數,您需要確保在最后一次函數調用之后不會發生乘法運算。
"use strict";
function factorial(n, p = 1) {
if (n <= 1) {
return 1 * p;
} else {
let result = n * p;
// optimized
return factorial(n - 1, result);
}
}
來源: Nicholas Zakas 的一本很棒的書,Understanding ECMAScript 6。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.