JavaScript arguments.callee作用及替換方案詳解
一、arguments.callee的作用:返回正被執(zhí)行的 Function 對(duì)象
arguments 的主要用途是保存函數(shù)參數(shù), 但這個(gè)對(duì)象還有一個(gè)名叫 callee 的屬性,返回正被執(zhí)行的 Function 對(duì)象,也就是所指定的 Function 對(duì)象的正文,這有利于匿名函數(shù)的遞歸或者保證函數(shù)的封裝性。
請(qǐng)看下面這個(gè)非常經(jīng)典的階乘函數(shù)
function factorial(num){ if (num <=1) { return 1; } else { return num * factorial(num-1) } }
定義階乘函數(shù)一般都要用到遞歸算法;如上面的代碼所示,在函數(shù)有名字,而且名字以后也不會(huì)變的情況下,這樣定義沒(méi)有問(wèn)題。
但問(wèn)題是這個(gè)函數(shù)的執(zhí)行與函數(shù)名 factorial 緊緊耦合在了一起。為了消除這種緊密耦合的現(xiàn)象,可以像下面這樣使用
arguments.callee
function factorial(num){ if (num <=1) { return 1; } else { return num * arguments.callee(num-1); } }
在這個(gè)重寫后的 factorial()函數(shù)的函數(shù)體內(nèi),沒(méi)有再引用函數(shù)名 factorial。這樣,無(wú)論引用函數(shù)時(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 如果沒(méi)有使用arguments.callee,將返回0
在此,變量 trueFactorial 獲得了 factorial 的值,實(shí)際上是在另一個(gè)位置上保存了一個(gè)函數(shù)的指針。然后,我們又將一個(gè)簡(jiǎn)單地返回 0的函數(shù)賦值給 factorial 變量。如果像原來(lái)的 factorial() 那樣不使用 arguments.callee,調(diào)用 trueFactorial()就會(huì)返回 0。可是,在解除了函數(shù)體內(nèi)的代碼與函數(shù)名的耦合狀態(tài)之后,trueFactorial()仍然能夠正常地計(jì)算階乘;至于factorial(),它現(xiàn)在只是一個(gè)返回 0的函數(shù)。
二、arguments.callee的替換方案
現(xiàn)在已經(jīng)不推薦使用arguments.callee();
原因:訪問(wèn) arguments 是個(gè)很昂貴的操作,因?yàn)樗莻€(gè)很大的對(duì)象,每次遞歸調(diào)用時(shí)都需要重新創(chuàng)建。影響現(xiàn)代瀏覽器的性能,還會(huì)影響閉包。
不能用怎么辦?
遞歸時(shí)用到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 被棄用了。怎么辦,其實(shí)很簡(jiǎn)單,給內(nèi)部函數(shù)一個(gè)名字即可(當(dāng)函數(shù)被調(diào)用時(shí),它的arguments.callee對(duì)象就會(huì)指向自身,也就是一個(gè)對(duì)自己的引用。)
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]
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
全面解析JavaScript中的valueOf與toString方法(推薦)
本文給大家介紹JavaScript中的valueOf與toString方法,valueOf() 方法可返回 Boolean 對(duì)象的原始值,toString() 方法可把一個(gè)邏輯值轉(zhuǎn)換為字符串,并返回結(jié)果。對(duì)js中valueof和tostring相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-06-06javascript彈性運(yùn)動(dòng)效果簡(jiǎn)單實(shí)現(xiàn)方法
這篇文章主要介紹了javascript彈性運(yùn)動(dòng)效果簡(jiǎn)單實(shí)現(xiàn)方法,實(shí)例分析了JavaScript實(shí)現(xiàn)彈性運(yùn)動(dòng)的原理,涉及JavaScript數(shù)學(xué)運(yùn)算與時(shí)間函數(shù)的相關(guān)使用技巧,需要的朋友可以參考下2016-01-01深入探討JavaScript中parseInt與Number數(shù)字轉(zhuǎn)換方法的區(qū)別
在Javascript編程中,數(shù)字是一種常見的數(shù)據(jù)類型,經(jīng)常需要在不同的情境下進(jìn)行不同類型的操作,本文將深入探討parseInt()和Number()的區(qū)別,通過(guò)代碼示例和詳細(xì)解釋,幫助大家更好地理解它們的用途,需要的朋友可以參考下2023-08-08js 將圖片連接轉(zhuǎn)換成base64格式的簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇js 將圖片連接轉(zhuǎn)換成base64格式的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08清華大學(xué)出版的事半功倍系列 javascript全部源代碼
清華大學(xué)出版的事半功倍系列 javascript全部源代碼...2007-05-05JS實(shí)現(xiàn)簡(jiǎn)單的todoList(記事本)效果
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)簡(jiǎn)單的todoList(記事本)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08