匿名递归 - 有什么方法可以将 javascript 'arguments.callee' 替换为其他符号,例如 'SELF'?

2024-04-01

我想替换jsarguments.callee到另一个符号,例如SELF.

是否可以?

宏观方法如sweetjs http://sweetjs.org/是唯一的办法吗?


EDIT

非常感谢您的投入:

我明白arguments.callee在严格模式下是被禁止的。

为了清楚起见,我展示我的代码:匿名递归

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

and now

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-组合器.

But, arguments.callee不能用这样的东西代替吗? 在Y-组合器场景,代码必须是

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

嵌套变得更深来定义阶乘等,我不愿意......


EDIT2

没过多久,一篇好文章就出现了。

6行Javascript的匿名递归 http://am.aurlien.net/post/2810658101/z-combinator

作者阿恩·马丁 (Arne Martin) 称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”,所以我们不用担心严格模式!


如果您不想使用严格模式,并且不介意使用全局变量和已弃用的功能,则可以向大多数现代 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”获取器相同的信息,并且在严格模式下工作并且没有全局变量。使用函数名称的一个缺点是你不能一遍又一遍地重复使用相同的符号,除非你使用专门命名的函数表达式,并给出你的函数和内部名称 self:

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

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

demo();
someOtherFunction();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

匿名递归 - 有什么方法可以将 javascript 'arguments.callee' 替换为其他符号,例如 'SELF'? 的相关文章

随机推荐