最近在看《Professional Javascript For Web Developers 3rd Edition》,看到關於遞歸函數調用的問題,在此記錄備忘:
先定義一個遞歸函數,求正整數N的階乘:
function factorial(num){ if(num<=1) return 1; return num*factorial(num-1); }
接着定義另外一個變量指向這個函數,然后將該函數置為null
var anotherFactorial=factorial; factorial=null; alert(anotherFactorial(4));//報錯
為什么會報錯呢?因為在函數factorial內部,遞歸調用了factorial本身,而上面的代碼將factorial置為null了,所以它不再是一個function。這聽上去有點奇怪,不過javascript內部就是這樣處理的。怎么解決這個問題呢?一個方法是用函數內部的arguments.callee替換函數本身
function factorial(num){ if(num<=1) return 1; return num * arguments.callee(num-1); }
這樣一來不管將函數賦值給哪個變量,之后的調用都不會有問題。因此,建議在遞歸函數內部用arguments.callee代替函數本身。或者也可以用函數表達式解決這個問題:
var factorial = (function f(num){ if(num<=1) return 1; return num*f(num-1); });
這樣不論是否將變量factorial變量賦值給另外的變量,遞歸調用都不會有問題。