JavaScript中arguments.callee屬性的作用與替換方案
arguments.callee的作用
在函數(shù)內(nèi)部,有兩個特殊的對象:arguments 和 this。其中, arguments 的主要用途是保存函數(shù)參數(shù), 但這個對象還有一個名叫 callee 的屬性,該屬性是一個指針,指向擁有這個 arguments 對象的函數(shù)。 請看下面這個非常經(jīng)典的階乘函數(shù)
function factorial(num){ if (num <=1) { return 1; } else { return num * factorial(num-1) } }
定義階乘函數(shù)一般都要用到遞歸算法;如上面的代碼所示,在函數(shù)有名字,而且名字以后也不會變 的情況下,這樣定義沒有問題。但問題是這個函數(shù)的執(zhí)行與函數(shù)名 factorial 緊緊耦合在了一起。為 了消除這種緊密耦合的現(xiàn)象,可以像下面這樣使用 arguments.callee
function factorial(num){ if (num <=1) { return 1; } else { return num * arguments.callee(num-1); } }
在這個重寫后的 factorial()函數(shù)的函數(shù)體內(nèi),沒有再引用函數(shù)名 factorial。這樣,無論引用 函數(shù)時使用的是什么名字,都可以保證正常完成遞歸調(diào)用。例如
function factorial(num){ if(num <= 1){ return 1; }else{ return num * arguments.callee(num-1); } } var trueFactorial = factorial; alert(trueFactorial(5)); //120 factorial = function() { return 0; } alert(trueFactorial(5));// 120 如果沒有使用arguments.callee,將返回0
在此,變量 trueFactorial 獲得了 factorial 的值,實際上是在另一個位置上保存了一個函數(shù) 的指針。然后,我們又將一個簡單地返回 0的函數(shù)賦值給 factorial 變量。如果像原來的 factorial() 那樣不使用 arguments.callee,調(diào)用 trueFactorial()就會返回 0??墒牵诮獬撕瘮?shù)體內(nèi)的代 碼與函數(shù)名的耦合狀態(tài)之后,trueFactorial()仍然能夠正常地計算階乘;至于 factorial(),它現(xiàn) 在只是一個返回 0的函數(shù)。
arguments.callee的替換方案
現(xiàn)在已經(jīng)不推薦使用arguments.callee();
原因:訪問 arguments 是個很昂貴的操作,因為它是個很大的對象,每次遞歸調(diào)用時都需要重新創(chuàng)建。影響現(xiàn)代瀏覽器的性能,還會影響閉包。
不能用怎么辦?
像第三段中的例子,重寫 factorial()方法導(dǎo)致trueFactorial()結(jié)果不在預(yù)期。是為了演示而做的。平時寫代碼應(yīng)該避免。
遞歸時用到arguments.callee()是常見的事情,比如
一道面試題。接受參數(shù)n=5,不用for循環(huán)輸出數(shù)組【1,2,3,4,5】
這用遞歸的思路,配合arguments.callee,代碼如下
function show(n) { var arr = []; return (function () { arr.unshift(n); n--; if (n != 0) { arguments.callee(); } return arr; })() } show(5)//[1,2,3,4,5]
現(xiàn)在arguments.callee 被棄用了。怎么辦,其實很簡單,給內(nèi)部函數(shù)一個名字即可
function show(n) { var arr = []; return (function fn() { arr.unshift(n); n--; if (n != 0) { fn(); } return arr; })() } show(5)//[1,2,3,4,5]
斐波那契遞歸算法替換
function factorial(num) { if (num <= 1) { return 1 } var fac = 1 return (function fn() { fac *= num num-- if (num != 0) { fn() } return fac })() } factorial(5) // 120
到此這篇關(guān)于JavaScript中arguments.callee屬性的作用與替換方案的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
一個非常好用的文字滾動的案例,鼠標(biāo)懸浮可暫停[兩種方案任選]
本文主要介紹了非常好用的文字滾動的案例,鼠標(biāo)懸浮可暫停的兩種實現(xiàn)方案,代碼簡潔,可收藏備用。需要的朋友來看下吧2016-12-12Javascript限制網(wǎng)頁只能在微信內(nèi)置瀏覽器中訪問
最近正在開發(fā)一個微信公眾賬號,其中有一項功能是用戶發(fā)送文字消息給公眾號,然后公眾號返回圖文消息給用戶,用戶再點擊圖文消息即可跳轉(zhuǎn)到一個網(wǎng)頁鏈接,在微信的內(nèi)置瀏覽器中打開。2014-11-11完美實現(xiàn)js拖拽效果 return false用法詳解
這篇文章主要為大家詳細介紹了完美實現(xiàn)js拖拽效果的代碼,一起學(xué)習(xí)return false的用法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07