1. 是什么?javascript
函数末尾只调用自身称为尾递归。java
2. 为何?es6
递归函数在调用时会在内存中保存调用位置和内部变量信息,造成一个调用栈。若是不加优化,有可能同时保存成百上千个调用记录。很容易发生栈溢出的错误。函数
尾调用函数因为是函数的最后一步操做,因此不须要保留外层函数的调用记录,由于调用位置和内部变量信息都不须要再用到了,只要直接用内存的调用记录取代外层的调用记录就能够了。因此不会发生栈溢出的错误。优化
3. 怎么办?this
实现尾递归只须要咱们在原来的函数基础上追加一个参数用来保存递归循环的值。固然这样会大大增长函数的有雅兴。因此优化方式能够有:spa
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
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
function factorial(n, total = 1) { if (n === 1) return total; return factorial(n - 1, n * total); } factorial(5) // 120