我试图理解 ES2015 中的生成器,并用它创建了一个递归阶乘函数。但它不起作用。我已经提到了已经存在的问题,例如 this关于这个话题,但没有帮助。
function* fact (n) {
if (n < 2) {
yield 1;
} else {
yield* (n * fact(n-1));
}
}
let b = fact(5);
console.log(b.next());
谁能找到我在这里遗漏的任何明显问题?我在带有 JavaScript-1.7 的 JSFiddle 中使用它 here
最佳答案
Can anyone find any obvious issues I am missing here?
fact
返回一个迭代器,但您正试图将它与一个数字 相乘:n * fact(n-1)
。那行不通!
因为 fact
返回一个迭代器,但您还想将迭代器的最后一个值与 n
相乘(即它不是尾递归的),您不能简单地yield*
要么。
您需要显式迭代内部调用的结果,重新发出值并记住最后一个值,以便您可以对其进行倍增:
function* fact (n) {
if (n < 2) {
yield 1;
} else {
let last;
for(last of fact(n-1)) {
yield last;
}
yield n * last;
}
}
Array.from(fact(5)); // [1, 2, 6, 24, 120]
如果将函数更改为尾递归,它会更短(更好),但结果也会不同(因为我们以不同的顺序执行操作,至少在这个实现中):
function* fact (n, acc=1) {
yield acc
if (n > 1) {
yield* fact(n-1, acc * n);
}
}
Array.from(fact(5)); // [1, 5, 20, 60, 120]
我个人只会写一个非递归版本:
function* fact (n) {
let result = 1;
let i = 0;
while (i < n) {
yield result = result * ++i;
}
}
Array.from(fact(5)); // [1, 2, 6, 24, 120]
关于javascript - 为什么递归生成器函数在 ES2015 中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37178782/