本文介绍了匿名递归 - 有什么方法可以将 javascript 'arguments.callee' 替换为其他符号,例如 'SELF'?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 js arguments.callee 替换为另一个符号,例如 SELF.

有可能吗?

sweetjs 等宏方法是唯一的方法吗?

编辑

非常感谢您的意见:

我了解 arguments.callee 在 StrictMode 中是被禁止的.

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

var factorial = function (n){返回 n ?n * arguments.callee(n - 1) : 1;};控制台日志(阶乘(10));//3628800

现在

var SELF = 函数 (val){返回 arguments.callee(val);}var factorial = 函数 (n){返回 n ?n * 自 (n - 1) : 1;};控制台日志(阶乘(10));

报错

var SELF = 函数 (val)^RangeError:超出最大调用堆栈大小

另外,我知道匿名递归有一种方法可以不使用arguments.callee,而是使用Y-Combinator.>

但是,arguments.callee 不能用这样的东西代替对吗?在Y-Combinator场景中,代码必须是

var f = function(f) {返回函数(n){返回 n ?n * f(n - 1) : 1;}}

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

EDIT2

过了很短的时间,一篇好文章就出现了.

6 行 Javascript 的匿名递归

作者 Arne Martin 称z-combinator:

var Z = function(func){var f = 函数 (){返回 func.apply(null, [f].concat([].slice.apply(arguments)));};返回 f;}var factorial = 函数 (f, n){返回 n ?n * f(n - 1) : 1;}console.log( Z(factorial)(10) );

这个方法完美地满足了我的需求,而且因为它不需要'arguments.callee',所以我们不用担心严格模式!

解决方案

如果你不想使用严格模式,并且不介意使用全局变量和不推荐使用的特性,你可以添加自定义只读关键字"到最现代的 JS 实现:

Object.defineProperty(自己,自己",{get:function(){return arguments.callee.caller;}//!!已弃用的功能正在使用中!!});功能演示(a,b){警报(自我);}函数 someOtherFunction(a,b){警报(自我);}演示();someOtherFunction();

这很酷,但有更强大和更现代的方法来做到这一点,即使用函数的名称:

function someAdditionalFunction(a,b){警报(一些附加功能);}

使用该名称可以获取与上面的SELF"getter 相同的信息,并且在严格模式下工作并且没有全局变量.使用函数名的一个缺点是你不能一遍又一遍地重复使用相同的符号,除非你使用专门命名的函数表达式,并给你的函数和 self 的内部名称:

var demo=function SELF(a,b){警报(自我);};var someOtherFunction=function SELF(a,b){警报(自我);};演示();someOtherFunction();

I want to replace js arguments.callee to another symbol like SELF.

Is it possible?

Macro approach such as sweetjs is the only way?


EDIT

Thanks a lot for inputs:

I understand arguments.callee is prohibited in StrictMode.

To make things clear, I present my code: anonymous recursion

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) );

gives an error

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

Also, I know there's a way for anonymous recursion not to use arguments.callee, instead to use Y-Combinator.

But, arguments.callee cannot be replaced by such a thing correct?In Y-Combinator Scenario, the code must be

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

The nest becomes deeper to define factorial, etc. which I am not willing to...


EDIT2

after a short period of time, a fine article hits.

Anonymous recursion in 6 lines of Javascript

The author Arne Martin calls 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) );

This method perfectly fills my needs, and also since it doesn't require 'arguments.callee', we don't worry about strict mode!

解决方案

if you do not want to use strict mode, and don't mind using global variables and deprecated features, you can add custom read-only "keywords" to most modern JS implementations:

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();

this is cool and all, but there are more robust and modern ways of doing this, namely using the function's name:

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

using the name lets you grab the same info as the "SELF" getter above, and works in strict mode and without global variables. The one downside to using function names is that you can't re-use the same symbol over and over, unless you use exclusively named function expressions, and give your functions and internal name of self:

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

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

demo();
someOtherFunction();

这篇关于匿名递归 - 有什么方法可以将 javascript 'arguments.callee' 替换为其他符号,例如 'SELF'?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 22:14