JavaScript 尾调用中的函数是否优化?
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
版本的函数是否会被 JavaScript 编译器优化,就像在 Scala 等其他语言中所做的那样。有人可以帮我解决这个问题吗?
更新:截至 2020 年 1 月 1 日,Safari 是唯一支持尾调用优化的浏览器。
Chromium 团队明确声明尾调用优化未在积极开发中,可以跟踪 here。
可以跟踪 Firefox 的实现 here
原版Post
是的,ES2015 提供了严格模式下的尾调用优化。 Axel Rauschmayer 博士在下面的 link 中进行了精美的阐述,所以我不会在这里重复他的话。
注意:ES 5 不优化尾调用。
理论上是的。正如其他答案所述。
但实际上,截至 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)
关注LINK
我一直试图在 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
版本的函数是否会被 JavaScript 编译器优化,就像在 Scala 等其他语言中所做的那样。有人可以帮我解决这个问题吗?
更新:截至 2020 年 1 月 1 日,Safari 是唯一支持尾调用优化的浏览器。
Chromium 团队明确声明尾调用优化未在积极开发中,可以跟踪 here。
可以跟踪 Firefox 的实现 here
原版Post
是的,ES2015 提供了严格模式下的尾调用优化。 Axel Rauschmayer 博士在下面的 link 中进行了精美的阐述,所以我不会在这里重复他的话。
注意:ES 5 不优化尾调用。
理论上是的。正如其他答案所述。
但实际上,截至 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)
关注LINK