我想将js arguments.callee
替换为另一个符号,例如 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-Combinator 。但是,
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
作者Arne Martin称 z-combinator :
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',因此我们不必担心严格的模式!
最佳答案
如果您不想使用严格模式,并且不介意使用全局变量和不建议使用的功能,则可以向大多数现代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” getter相同的信息,并且可以在严格模式下使用,而没有全局变量。使用函数名称的一个缺点是,除非您使用专门命名的函数表达式,并且不能给函数和内部名称self,否则不能一再重复使用相同的符号:
var demo=function SELF(a,b){
alert(SELF);
};
var someOtherFunction=function SELF(a,b){
alert(SELF);
};
demo();
someOtherFunction();
关于javascript - 匿名递归-是否可以将javascript 'arguments.callee'替换为其他符号(例如 'SELF')?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17645356/