3

我想将 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 Scenario 中,代码必须是

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

巢变得更深以定义我不愿意的阶乘等...


编辑2

不一会儿,一篇好文章就来了。

6行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',我们不用担心严格模式!

4

2 回答 2

2

如果您不想使用严格模式,并且不介意使用全局变量和不推荐使用的功能,您可以将自定义只读“关键字”添加到大多数现代 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();
于 2013-07-15T01:16:50.347 回答
0

这是我过去为不想使用的自引用函数所做的arguments.callee。只需在函数定义中输入一个名称:

var factorial = function factorialcallee(n)
{
    return n ? n * factorialcallee(n - 1) : 1;
};
console.log( factorial(10) );  //3628800
于 2013-07-24T09:23:19.330 回答