函数的尾递归

1. 是什么?javascript

函数末尾只调用自身称为尾递归。java

2. 为何?es6

递归函数在调用时会在内存中保存调用位置内部变量信息,造成一个调用栈。若是不加优化,有可能同时保存成百上千个调用记录。很容易发生栈溢出的错误。函数

尾调用函数因为是函数的最后一步操做,因此不须要保留外层函数的调用记录,由于调用位置和内部变量信息都不须要再用到了,只要直接用内存的调用记录取代外层的调用记录就能够了。因此不会发生栈溢出的错误。优化

3. 怎么办?this

实现尾递归只须要咱们在原来的函数基础上追加一个参数用来保存递归循环的值。固然这样会大大增长函数的有雅兴。因此优化方式能够有:spa

  1. 另外增长一个正常的函数
    function tailFactorial(n, total) { if (n === 1) return total; return tailFactorial(n - 1, n * total); } function factorial(n) { return tailFactorial(n, 1); } factorial(5) // 120
  2.  使用函数currying的思想
    function currying(fn, n) { return function (m) { return fn.call(this, m, n); }; } function tailFactorial(n, total) { if (n === 1) return total; return tailFactorial(n - 1, n * total); } const factorial = currying(tailFactorial, 1); factorial(5) // 120
  3.  使用es6提供的默认值
    function factorial(n, total = 1) { if (n === 1) return total; return factorial(n - 1, n * total); } factorial(5) // 120
相关文章
相关标签/搜索