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)文章
JavaScript中防抖和節(jié)流的區(qū)別及適用場景
這篇文章主要介紹了JavaScript中防抖和節(jié)流的區(qū)別及適用場景,文章通過圍繞主題的相關(guān)資料展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-05-05
JavaScript中cookie工具函數(shù)封裝的示例代碼
這篇文章給大家主要介紹了JavaScript中cookie工具函數(shù)的封裝,文中給出了詳細(xì)的實現(xiàn)步驟和示例代碼,相信會對大家的理解很有幫助,有需要的朋友們下面來一起看看吧。2016-10-10
JS和jQuery使用submit方法無法提交表單的原因分析及解決辦法
這篇文章主要介紹了JS和jQuery使用submit方法無法提交表單的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-05-05
JS實現(xiàn)鼠標(biāo)拖拽盒子移動及右鍵點(diǎn)擊盒子消失效果示例
這篇文章主要介紹了JS實現(xiàn)鼠標(biāo)拖拽盒子移動及右鍵點(diǎn)擊盒子消失效果,涉及javascript事件響應(yīng)及頁面元素屬性動態(tài)操作相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2019-01-01

