28

この変数の完全なクロスブラウザドキュメントは見つかりませんでした。

arguments.calleeのために?それはどのように機能しますか?

どの議論がありますか?

4

5 に答える 5

31

arguments.callee現在呼び出されている関数への参照です。まず最初に:使用しないでください。厳密なコンテキストにいる場合は、エラーが発生するだけです。

しかし、個人的に-そして私はこれで一人ではありません-私はこのプロパティを逃します。理由を説明する前に、これを使用する場合の疑似例を示します。

var looper = (function(someClosureVar)
{
    setTimeout((function(resetTimeout)
    {
        return function()
        {
            //do stuff, stop OR:
            resetTimeout();
        };
    }(arguments.callee)),1000);
}(document.getElementById('foobar')));

私がそうしているので、あなたが閉鎖を好むことを願っています-そしてそれarguments.calleeは非常に起こりそうな場所です。最後から2番目の行は、お金がどこにあるかです。

(arguments.callee)

クロージャスコープ内(この場合は1つのDOM要素にアクセスできる)で初期タイムアウトを設定する無名関数への参照です。匿名関数は戻った後にGCされますが、この場合、タイムアウトコールバックのスコープに追加したので(実際のコールバックを返す別の匿名関数への引数として渡しました)、それでもどこかで参照されます。
厳密に設定している場合は、これが厳密モードでのコードのようになるため、心配する必要はありません。

var looper = (function tempName(someClosureVar)
{
    setTimeout((function(resetTimeout)
    {
        return function()
        {
            //do stuff, stop OR:
            resetTimeout();
        };
    }(tempName)),1000);
}(document.getElementById('foobar')));

関数に名前を付けると、それだけです。なぜ私はそれが好きではないのですか?arguments.calleeクロージャのトリックが行われている匿名関数のように、フラグを立てます。それは単なる習慣だと思いますが、コードをより簡単に構造化してデバッグするのに役立つと思います。
それをIEに対する病的な憎しみと結びつけてください。これは、クライアント側のスクリプトを作成する人にとっては当然のことです。厳密モードをサポートしないIEバージョンは、関数名をグローバル名前空間にリークする傾向があるため、関数に関連付けられたメモリ(および作成したクロージャ)をGCすることはできません。これは循環参照につながる可能性があり、さらに悪いことに、メモリリークにつながる可能性のある循環DOM参照につながる可能性があります。

実際:使用されている場所のもう1つの実際の例arguments.calleeは、次のとおりです。イベントの委任とイベントリスナーのデタッチについては、JSの厳密モードとを使用した再帰
に関する詳細情報arguments.calleeを参照してください。

最後の質問は、IMOがどのように便利であるかを示す最も明確な例ですarguments.callee。再帰的な置換関数:

function someF(foo)
{
    //'use strict'; <-- would throw errors here
    foo = foo.replace(/(a|b)+/gi, function (p1,p2)
    {
        if (p1.match(/(a|b){2,}/i))
        {
            return p1.replace(/(a|b)/gi,arguments.callee);//recursive
        }
        return (p2.match(/a/i) ? 'X':'Y');
    });
}

MDNでarguments.calleeが要求されると、 strict
モードでの使用について警告します(ECMA 5、DCがarguments.calleeが非推奨となる理由を説明します)

于 2012-08-21T08:30:16.650 に答える
5

現在実行中の関数を指定し、現在の関数も指定しarguments.calleeます。匿名関数で再帰的に実行する必要がある場合に役立つことがあります。ここにmozillaからの例があります:

function create() {
   return function(n) {
      if (n <= 1)
         return 1;
      return n * arguments.callee(n - 1);
   };
}

var result = create()(5); // returns 120 (5 * 4 * 3 * 2 * 1)
于 2012-08-21T07:41:22.870 に答える
4

CaleeはECMAScript3標準の一部であるため、クロスブラウザーでの使用には安全です。Calleeは現在実行中の関数を保持しており、それを呼び出すと現在の関数が呼び出されます。したがって、呼び出し先は、囲んでいる関数とまったく同じ引数を取ります(つまり現在の関数です)。詳細については、https ://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/calleeをご覧ください。

calleeを使用するのは悪いスタイルと見なされます。代わりに関数に名前を付けて、この名前を使用してください...

于 2012-08-21T07:38:47.877 に答える
3

arguments.calleeは、「この特定の引数を誰が呼び出しているのか」と尋ねることによって、現在実行中の関数を知る方法についてのラウンドアバウトです。。。。。

 function factorial(a){
    if(a>0)
      return a*arguments.callee(a-1);
 }

ここでfactorial(5)を呼び出すと、0より大きい条件がチェックされ、trueの場合、次の小さい数値に対して同じロジックが実行されます。。。呼び出される関数の名前がわからない場合があります。。。.soこのプロパティを使用できます

ここに良いリファレンスがあります

MDNからのarguments.callee

更新: arguments.callee() ES5では非推奨です

于 2012-08-21T07:42:37.613 に答える
2

calleeはargumentsオブジェクトのプロパティです。これは、その関数の関数本体内で現在実行中の関数を参照するために使用できます。

MDNドキュメントはこちら

于 2012-08-21T07:38:42.710 に答える