微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript – 为什么递归生成器函数在ES2015中不起作用?

我试图了解ES2015中的生成器,并创建了一个递归因子函数.但它不行.我已经提到已经存在的问题,如 this这个话题,但这没有帮助.
function* fact (n) {
   if (n < 2) {
     yield 1;
   } else {
     yield* (n * fact(n-1));
   }
}

let b = fact(5);
console.log(b.next());

任何人都会发现我在这里遗失的明显问题吗?我在JSfiddle中使用了JavaScript-1.7 here

解决方法

Can anyone find any obvIoUs issues I am missing here?

事实返回一个迭代器,但是你试图用一个数字来重复它:n * fact(n-1).那不行!

因为事实返回一个迭代器,但是你也希望将迭代器的最后一个值乘以n(即它不是尾递归),所以你也不能简单地生成它.
您需要从内部调用中显式迭代结果,重新引用该值并记住最后一个值,以便可以使用多个值:

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,120]

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐