![](/img/trans.png)
[英]Simple tail-call optimization for recursive, while-loop style functions
[英]Are functions in JavaScript tail-call optimized?
我一直在嘗試了解 JavaScript 上下文中的Tail call optimization
,並為factorial()
編寫了以下遞歸和尾遞歸方法。
遞歸:
function factorial (n) {
if (n < 2) {
return 1;
} else {
return n * factorial(n-1);
}
}
尾遞歸:
function factorial (n) {
function fact(n, acc) {
if (n < 2) {
return acc;
} else {
return fact(n-1, n * acc);
}
}
return fact(n, 1)
}
但我不確定該函數的tail-recursive
版本是否會像在其他語言(如 Scala 等)中一樣由 JavaScript 編譯器優化。有人可以幫我解決這個問題嗎?
理論上是的。 正如另一個答案所述。
但實際上,截至 2017 年 7 月,否。只有 Safari 支持它。
Javascript ES6 (ES2015) 兼容性: https ://kangax.github.io/compat-table/es6/
正如其他答案所說,實際上並非如此。 但是,您可以定義一個實用程序來提供幫助。
class Tco {
constructor(func) {
this.func = func;
}
execute() {
let value = this;
while (value instanceof Tco)
value = value.func();
return value;
}
}
const tco = (f) => new Tco(f);
function factorial (n) {
const fact = (n, acc) => tco(() => {
if (n < 2) {
return acc;
} else {
return fact(n-1, n * acc);
}
});
return fact(n, 1).execute();
}
console.log(factorial(2000000)); // Infinity
如您所見,這允許您編寫僅在語法上有很小差異的尾遞歸函數,而不會遇到最大調用堆棧錯誤。
Safari 是唯一支持尾調用優化的瀏覽器。 ES2015 在嚴格模式下提供尾調用優化
function factorial(n, returnVal= 1) {
'use strict';
if (n <= 1) return returnVal;
return factorial(n - 1, n * returnVal);
}
factorial(555)
按照鏈接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.