2013-07-15 25 views
3

我想將js arguments.callee替換爲另一個符號,如SELF匿名遞歸 - 將javascript'arguments.callee'替換爲其他symol如'SELF'的任何方式?

可能嗎?

宏觀方法如sweetjs是唯一的方法?


編輯

非常感謝輸入:

我明白arguments.callee禁止在StrictMode。

爲了把事情說清楚,我提出我的代碼:匿名遞歸

var factorial = function (n) 
{ 
    return n ? n * arguments.callee(n - 1) : 1; 
}; 
console.log(factorial(10)); //3628800 

現在

var SELF = function (val) 
{ 
    return arguments.callee(val); 
} 
var factorial = function (n) 
{ 
    return n ? n * SELF(n - 1) : 1; 
}; 
console.log(factorial(10)); 

給出了一個錯誤

var SELF = function (val) 
        ^
RangeError: Maximum call stack size exceeded 

而且,我知道有一個匿名遞歸方式不使用arguments.callee,而是使用Y組合器

但是,arguments.callee不能被這樣的東西替換是否正確? 在的Y Combinator的情況下,代碼必須

var f = function(f) { 
      return function(n){ 
       return n ? n * f(n - 1) : 1; 
      } 
     } 

巢變得更深定義階乘,等我不甘心......


EDIT2

很短的時間後,一篇精美的文章點擊。

Anonymous recursion in 6 lines of Javascript

筆者阿恩·馬丁稱Z-組合子

var Z = function(func) 
{ 
    var f = function() 
    { 
     return func.apply(null, [f].concat([].slice.apply(arguments))); 
    }; 
    return f; 
} 

var factorial = function (f, n) 
{ 
    return n ? n * f(n - 1) : 1; 
} 

console.log( Z(factorial)(10)); 

這種方法完全填滿我的需要,同時也因爲它不需要 'arguments.callee的',我們不不擔心嚴格模式!

+0

您可以使用命名函數表達式並在其中使用該名稱。 – elclanrs

+0

難道你不能只使用'var SELF = arguments.callee;'或者我在這裏丟失了一些東西。 – Shawn31313

+1

只是單挑:使用'arguments.callee'會在嚴格模式下拋出一個'TypeError'。 – founddrama

回答

3

,如果你不希望使用嚴格模式,並且不介意使用全局變量和不贊成使用的功能,您可以添加自定義只讀「關鍵詞」,以最現代的JS實現:

Object.defineProperty(
self, 
"SELF", 
{get:function(){return arguments.callee.caller;} //!! deprecated feature in use!! 
}); 


function demo(a,b){ 
    alert(SELF); 
} 

function someOtherFunction(a,b){ 
    alert(SELF); 
} 



demo(); 
someOtherFunction(); 

這是冷靜和所有,但也有這樣做,即使用函數的名稱更強大和現代的方式:

function someAdditionalFunction(a,b){ 
    alert(someAdditionalFunction); 
} 

使用,您可以獲取相同的信息爲「SELF」吸除上面的名稱,並在工作嚴格模式並且沒有全局變量。一個缺點,使用功能名稱是,你不能一遍又一遍地重複使用相同的符號,除非你使用專門命名的函數表達式,並給您的功能和自我的內部名稱:

var demo=function SELF(a,b){ 
    alert(SELF); 
}; 

var someOtherFunction=function SELF(a,b){ 
    alert(SELF); 
}; 

demo(); 
someOtherFunction(); 
+1

對命名函數表達式非常小心 - IE使它們成爲全局變量。 – RobG

+0

等等,真的嗎?即使在今天? – ehdv

+0

快速搜索說至少IE8。沒有關於IE9 +的線索。 – Havvy

1

這是我在過去爲自我參考功能做了什麼,我不想使用arguments.callee。只需在函數定義中添加一個名稱:

var factorial = function factorialcallee(n) 
{ 
    return n ? n * factorialcallee(n - 1) : 1; 
}; 
console.log(factorial(10)); //3628800