JavaScript遞迴

wade3po發表於2019-04-03

遞迴的定義很簡單,就是在函式體內呼叫本函式。遞迴對於解決一些演算法問題有很大的優勢,但是遞迴必須慎重使用,遞迴函式如果判斷條件無法終止,很容易造成記憶體溢位,報錯stack overflow,使程式崩潰。

遞迴最經典例子,階乘:

階乘就是12345......

計算階乘的函式factorial:

function  factorial(num) { 
   if (num == 0) {  
      return 1; 
   };
   return num * factorial(num - 1);
}
複製程式碼

我們分享過呼叫棧了,當我們呼叫factorial(5)的時候,函式執行過程中需要快取變數,從5一直到2。這對記憶體使用會比較多。所以有些函式可以處理成尾遞迴:

function factorial (n, total = 1) { 
   if(n == 1){ 
       return total; 
   }    
    return factorial(n-1, n * total);
}
複製程式碼

這樣每次都是執行函式,不需要快取區域性變數。

斐波那契數列:

斐波那契數列指的是1、1、2、3、5、8……這樣的數列,數學應該都學過,可以推匯出公式:F(n) = F(n-1) + F(n-2),且引數大於3。

function fn(n) { 
   if (n < 3) { 
       return 1; // 遞迴終止條件  
  }    
  return fn(n - 1) + fn(n - 2);
}
複製程式碼

通過呼叫棧知道,這會形成非常多的呼叫棧,其實並不推薦使用遞迴算斐波那契數列,使用迴圈會是更好的選擇。

遞迴在開發業務過程中基本很難用上,不可能讓你寫個階乘寫個斐波那契數列。之前水群的時候有人問了個問題:

JavaScript遞迴

上面列印orderId明明不一樣的, 但是放在下面的迴圈 結果都一樣了?

像這種場景下就可以使用遞迴,因為請求是非同步的,當你成功的時候i可能已經迴圈到了最後了,這時候在成功回撥裡面使用遞迴就能很好解決這個問題。

其他的具體業務使用場景還真的沒有很多想法,這邊再提一嘴,慎重使用遞迴,遞迴總結條件一定要很清晰,遞迴很容易記憶體溢位。

Coding 個人筆記

JavaScript遞迴

相關文章