JavaScript中arguments.callee屬性的作用與替換方案
arguments.callee的作用
在函數(shù)內(nèi)部,有兩個(gè)特殊的對(duì)象:arguments 和 this。其中, arguments 的主要用途是保存函數(shù)參數(shù), 但這個(gè)對(duì)象還有一個(gè)名叫 callee 的屬性,該屬性是一個(gè)指針,指向擁有這個(gè) arguments 對(duì)象的函數(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è)重寫(xiě)后的 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ì)影響閉包。
不能用怎么辦?
像第三段中的例子,重寫(xiě) factorial()方法導(dǎo)致trueFactorial()結(jié)果不在預(yù)期。是為了演示而做的。平時(shí)寫(xiě)代碼應(yīng)該避免。
遞歸時(shí)用到arguments.callee()是常見(jiàn)的事情,比如
一道面試題。接受參數(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è)名字即可
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屬性的作用與替換方案的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript中防抖和節(jié)流的區(qū)別及適用場(chǎng)景
這篇文章主要介紹了JavaScript中防抖和節(jié)流的區(qū)別及適用場(chǎng)景,文章通過(guò)圍繞主題的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05
JavaScript中cookie工具函數(shù)封裝的示例代碼
這篇文章給大家主要介紹了JavaScript中cookie工具函數(shù)的封裝,文中給出了詳細(xì)的實(shí)現(xiàn)步驟和示例代碼,相信會(huì)對(duì)大家的理解很有幫助,有需要的朋友們下面來(lái)一起看看吧。2016-10-10
JS和jQuery使用submit方法無(wú)法提交表單的原因分析及解決辦法
這篇文章主要介紹了JS和jQuery使用submit方法無(wú)法提交表單的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-05-05
JS實(shí)現(xiàn)鼠標(biāo)拖拽盒子移動(dòng)及右鍵點(diǎn)擊盒子消失效果示例
這篇文章主要介紹了JS實(shí)現(xiàn)鼠標(biāo)拖拽盒子移動(dòng)及右鍵點(diǎn)擊盒子消失效果,涉及javascript事件響應(yīng)及頁(yè)面元素屬性動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-01-01
uni-app和web-view頁(yè)面相互傳參方法實(shí)例
web-view是一個(gè)web瀏覽器組件,可以用來(lái)承載網(wǎng)頁(yè)的容器,會(huì)自動(dòng)鋪滿整個(gè)頁(yè)面,下面這篇文章主要給大家介紹了關(guān)于uni-app和web-view頁(yè)面相互傳參的相關(guān)資料,需要的朋友可以參考下2023-06-06

