如何修改此代码以在 ES6 中启用尾调用优化?

How to modify this code to enable tail call optimization in ES6?

我写了一个递归求和的函数,但它不符合 ES6 中尾调用优化的标准(原因我说不清楚)。

function sum(...values) {
  if(!values.length) { 
    return 0; 
  }
  return values.shift() + sum(...values);
}

如何更改它以符合优化条件?

你需要做

return sum(…);

做一个合适的tail call。在您的示例中,+ 操作仍在 递归调用后 执行,这使得它不起作用。

典型的方法是使用带有累加器参数的辅助函数:

 function sum(...values) {
     function sumTo(acc, values) {
         if (!values.length) return acc;
         else return sumTo(acc+values.shift(), values); // tail-recursive call
     }
     return sumTo(0, values);
 }

递归列表时,您还可以(ab)使用列表本身:

function sum(...values) {
    switch (values.length) {
        case 0:  return 0;
        case 1:  return values[0];
        default: values.unshift(values.shift()+values.shift());
                 return sum(...values);
    }
}
// or alternatively:
function sum(acc, ...values) {
    switch (arguments.length) {
        case 0:  return 0;
        case 1:  return acc;
        default: values[0] += acc;
                 return sum(...values);
    }
}