學習 JavaScript 中的遞迴基礎
函式可以自己呼叫自己。
這就是遞迴的意思,它能夠以一個整潔的方式解決問題。
要達到這一點,您需要一個命名的函式表達式,換句話說,就是這樣:
function doSomething() {
}
所以我們可以在 doSomething()
內部呼叫 doSomething()
。
我們可以用計算數字的階乘來做最簡單的例子。這是我們通過將數字乘以 (數字 - 1),(數字 - 2) 等等,直到達到數字 1 而得到的數字。
數字 4 的階乘是 (4 * (4 - 1) * (4 - 2) * (4 - 3)) = 4 * 3 * 2 * 1,等於 24。
我們可以創建一個遞迴函式來自動計算:
function factorial(n) {
return n >= 1 ? n \* factorial(n - 1) : 1
}
factorial(1) //1
factorial(2) //2
factorial(3) //6
factorial(4) //24
我們也可以使用箭頭函式:
const factorial = (n) => {
return n >= 1 ? n \* factorial(n - 1) : 1
}
factorial(1) //1
factorial(2) //2
factorial(3) //6
factorial(4) //24
現在是談論一下呼叫堆疊的好時機。
想像一下,如果我們犯了個錯誤,而不是像這樣計算階乘:
const factorial = (n) => {
return n >= 1 ? n \* factorial(n - 1) : 1
}
我們卻這樣寫:
const factorial = (n) => {
return n >= 1 ? n \* factorial(n) : 1
}
如您所見,我們一直不斷地呼叫 factorial(n)
。沒有結束,因為我們忘了在每次呼叫時將其減少。
如果您運行此代碼,您將得到此錯誤:
RangeError: Maximum call stack size exceeded
每當一個函式被調用時,JavaScript 需要在切換到新內容之前記住當前上下文,因此它將這個上下文放入呼叫堆疊中。一旦函式返回,JavaScript會轉到呼叫堆疊並選擇最後添加的元素,並恢復其執行。
超出最大呼叫堆疊大小意味著太多的元素被放入堆疊中,使您的程式崩潰。