遞歸函數(shù)是在一個(gè)函數(shù)通過(guò)名字調(diào)用自身的情況下構(gòu)成的。
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * factorial(num - 1);
}
}
上例是一個(gè)經(jīng)典的遞歸階乘函數(shù)。雖然這個(gè)函數(shù)表面看來(lái)沒(méi)什么問(wèn)題,但下面的代碼卻可能導(dǎo)致它出錯(cuò)。
var anotherFactorial = factorial;
factorial = null
alert(anotherFactorial(4)); // error
上例代碼先把 factorial() 函數(shù)保存在變量 anotherFactorial 中,然后將 factorial 變量設(shè)置為 null,結(jié)果指向原始函數(shù)的引用只剩下一個(gè)。但在接下來(lái)調(diào)用 anotherFactorial() 時(shí),由于必須執(zhí)行 factorial(),而 factorial 已經(jīng)不再是函數(shù),所以就會(huì)導(dǎo)致錯(cuò)誤。
在這種情況下可以使用 arguments.callee 可以解決這個(gè)問(wèn)題。
arguments.callee 是一個(gè)指向正在執(zhí)行的函數(shù)的指針,因此可以用它來(lái)實(shí)現(xiàn)對(duì)函數(shù)的遞歸調(diào)用。
function factorial(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num - 1);
}
}
通過(guò)使用 arguments.callee 代替函數(shù)名,可以確保無(wú)論怎樣調(diào)用函數(shù)都不會(huì)出問(wèn)題。在編寫(xiě)遞歸函數(shù)時(shí),使用 argument.callee 總比使用函數(shù)名保險(xiǎn)
注意:在嚴(yán)格模式下,不能通過(guò)腳本訪問(wèn) arguments.callee 訪問(wèn)這個(gè)屬性會(huì)導(dǎo)致錯(cuò)誤。不過(guò)可以使用命名函數(shù)表達(dá)式來(lái)達(dá)成相同的結(jié)果。
var factorial = (function f(num) {
if (num <= 1) {
return 1;
} else {
return num * f(num - 1);
}
})