遞迴的定義很簡單,就是在函式體內呼叫本函式。遞迴對於解決一些演算法問題有很大的優勢,但是遞迴必須慎重使用,遞迴函式如果判斷條件無法終止,很容易造成記憶體溢位,報錯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);
}
複製程式碼
通過呼叫棧知道,這會形成非常多的呼叫棧,其實並不推薦使用遞迴算斐波那契數列,使用迴圈會是更好的選擇。
遞迴在開發業務過程中基本很難用上,不可能讓你寫個階乘寫個斐波那契數列。之前水群的時候有人問了個問題:
上面列印orderId明明不一樣的, 但是放在下面的迴圈 結果都一樣了?
像這種場景下就可以使用遞迴,因為請求是非同步的,當你成功的時候i可能已經迴圈到了最後了,這時候在成功回撥裡面使用遞迴就能很好解決這個問題。
其他的具體業務使用場景還真的沒有很多想法,這邊再提一嘴,慎重使用遞迴,遞迴總結條件一定要很清晰,遞迴很容易記憶體溢位。
Coding 個人筆記