function Fibonacci(n) { if (n === 1 || n === 2) { return 1 } return Fibonacci(n-1) + Fibonacci(n-2) }
遞歸最大的問題就是當調用幀過多時致使內存溢出html
function Fibonacci(n) { let arr = [0, 1] // 把計算過的結果存儲在數組裏 return (n) => { if (arr[n] === undefined) { arr[n] = Fibonacci(n-1) + Fibonacci(n-2) } return arr[n] } }
function Fibonacci(n) { let res1 = 1 let res2 = 2 if (n === 1 || n === 2) { return res2 } for(let i = 3; i <= n; i++) { [res1, res2] = [res2, res1 + res2] } return res2 }
尾調用之因此與其餘調用不一樣,就在於它的特殊的調用位置。es6
咱們知道,函數調用會在內存造成一個「調用記錄」,又稱「調用幀」(call frame),保存調用位置和內部變量等信息。若是在函數A
的內部調用函數B
,那麼在A
的調用幀上方,還會造成一個B
的調用幀。等到B
運行結束,將結果返回到A
,B
的調用幀纔會消失。若是函數B
內部還調用函數C
,那就還有一個C
的調用幀,以此類推。全部的調用幀,就造成一個「調用棧」(call stack)。數組
尾調用因爲是函數的最後一步操做,因此不須要保留外層函數的調用幀,由於調用位置、內部變量等信息都不會再用到了,只要直接用內層函數的調用幀,取代外層函數的調用幀就能夠了。閉包
詳情參閱函數擴展之尾調用優化——阮一峯。函數
function Fibonacci(n, res1 = 1, res2 = 1) { if (n <= 2) { return res2 } return Fibonacci(n-1, res2, res1 + res2) }
參考:
https://www.cnblogs.com/zkfop...
https://www.cnblogs.com/super...
https://blog.csdn.net/qq_3930...優化