编程语言
首页 > 编程语言> > javascript – 尾调用优化递归函数

javascript – 尾调用优化递归函数

作者:互联网

这是一个深度展平数组的函数

const deepFlatten = (input) => {
  let result = [];
  input.forEach((val, index) => {
    if (Array.isArray(val)) {
      result.push(...deepFlatten(val));
    } else {
      result.push(val);
    }
  });
  return result;
};

在讨论过程中,我被告知它不具有内存效率,因为它可能会导致堆栈溢出.

我在http://2ality.com/2015/06/tail-call-optimization.html读到我可能会重写它以便它被TCO编辑.

它会是什么样子,我怎么能测量它的内存使用情况?

解决方法:

当递归调用在forEach中时,您无法对其进行优化,因为为了应用TCO,编译器需要检查您是否保存了前一次调用的“状态”.在forEach的情况下,您确实保存当前位置的“状态”.

为了使用TCO实现它,您可以重写使用递归调用实现的foreach,它看起来像这样:

function deepFlattenTCO(input) {
  const helper = (first, rest, result) => {
    if (!Array.isArray(first)) {
      result.push(first);
      if (rest.length > 0) {
        return helper(rest, [], result);
      } else {
        return result;
      }
    } else {
      const [newFirst, ...newRest] = first.concat(rest);

      return helper(newFirst, newRest, result);
    }
  };

  return helper(input, [], []);
}

console.log(deepFlattenTCO([
  [1], 2, [3], 4, [5, 6, [7]]
]));

您可以看到,在每个返回中,执行的唯一操作是递归调用,因此,您不会在递归调用之间保存“状态”,因此编译器将应用优化.

标签:javascript,tail-recursion
来源: https://codeday.me/bug/20190823/1698951.html