3

js をSELFarguments.calleeのような別のシンボルに置き換えたい。

出来ますか?

sweetjsなどのマクロアプローチが唯一の方法ですか?


編集

たくさんのご意見ありがとうございます:

arguments.calleeStrictMode では禁止されていることを理解しています。

明確にするために、コードを提示します:匿名再帰

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

また、匿名再帰で を使用せずにY-Combinatorarguments.calleeを使用する方法があることも知っています。

でも、arguments.calleeそんなものに置き換えられないよね?Y コンビネーターシナリオでは、コードは

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

私が望んでいない階乗などを定義するために、巣はより深くなります...


EDIT2

しばらくすると、良品が当たります。

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」を必要としないため、strict モードについて心配する必要もありません。

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」ゲッターと同じ情報を取得でき、厳密モードでグローバル変数なしで機能します。関数名を使用することの 1 つの欠点は、名前付き関数式のみを使用し、関数と内部名に 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 に答える