函數的尾遞歸

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
相關文章
相關標籤/搜索