1

無名関数の名前を見つけることは可能ですか?

anonyFuたとえば、またはfindMeこのコードで警告する方法を見つけようとしていますhttp://jsfiddle.net/L5F5N/1/

function namedFu(){
    alert(arguments.callee);
    alert(arguments.callee.name);
    alert(arguments.callee.caller);
    alert(arguments.caller);
    alert(arguments.name);
}

var anonyFu = function() {
    alert(arguments.callee);
    alert(arguments.callee.name);
    alert(arguments.callee.caller);
    alert(arguments.caller);
    alert(arguments.name);
}

var findMe= function(){ 
    namedFu();
    anonyFu();
}
findMe();

これは一部の内部テスト用であるため、クロスブラウザーである必要はありません。実際、プラグインをインストールする必要があったとしても、私は満足しています。

4

5 に答える 5

1

あなたがそれを持っている方法が可能であることは間違いありません。手始めに、行を追加した場合

var referenceFu = anonyFu;

それらの名前のどれをログに記録できると思いますか?どちらも単なる参照です。

ただし、コードを変更できると仮定すると、これは有効なJavaScriptです。

var anonyFu = function notActuallyAnonymous() {
    console.log(arguments.callee.name);
}

ログに記録されます"notActuallyAnonymous"。したがって、コードを壊すことなく、チェックしたいすべての無名関数に名前を追加することができます。

それが役立つかどうかはわかりませんが、私が得たのはそれだけです。

于 2012-11-06T22:43:25.050 に答える
1

Arguments.callee を使用することで、名前のない無名関数であっても、プログラムによって関数の内部から任意のプロパティを識別できます。したがって、次の簡単なトリックで関数を識別できます。

関数を作成するときはいつでも、後で識別するために使用できるプロパティを割り当てます。

たとえば、常に id というプロパティを作成します。

var fubar = function() {
   this.id = "fubar";
   //the stuff the function normally does, here
   console.log(arguments.callee.id);
}

arguments.callee は関数自体であるため、その関数の任意のプロパティは、上記の id のように、自分で割り当てたものでもアクセスできます。

Callee は公式には非推奨ですが、ほとんどすべてのブラウザーで引き続き機能し、特定の状況ではまだ代替手段がありません。「厳密モード」では使用できません。

もちろん、代わりに、次のように無名関数に名前を付けることもできます。

var fubar = function foobar() {
   //the stuff the function normally does, here
   console.log(arguments.callee.name);
}

しかし、(この場合) 両方の場所で fubar という名前を付けることはできないため、明らかにエレガントではありません。私は実際の名前をfoobarにしなければなりませんでした。

すべての関数にそれらを説明するコメントがある場合は、次のようにそれを取得することもできます。

var fubar = function() {
   /* 
      fubar is effed up beyond all recognition 
      this returns some value or other that is described here
    */
   //the stuff the function normally does, here
   console.log(arguments.callee.toString().substr(0, 128);
}

現在の関数を呼び出した関数にアクセスするには、argument.callee.caller を使用することもできます。これにより、関数の外部から関数の名前 (または id やテキスト内のコメントなどのプロパティ) にアクセスできます。

これを行う理由は、問題の関数を呼び出したものを見つけたいからです。そもそも、この情報をプログラムで見つけたいと思うのは、おそらくこれが理由です。

したがって、上記の fubar() の例の 1 つが次の関数を呼び出したとします。

var kludge = function() {
   console.log(arguments.callee.caller.id); // return "fubar" with the first version above
   console.log(arguments.callee.caller.name); // return "foobar" in the second version above
   console.log(arguments.callee.caller.toString().substr(0, 128);
     /* that last one would return the first 128 characters in the third example, 
        which would happen to include the name in the comment. 
        Obviously, this is to be used only in a desperate case, 
        as it doesn't give you a concise value you can count on using)
     */
}
于 2014-01-23T19:40:40.537 に答える
1

その関数がどのオブジェクトにあるかがわかっている場合は、値に基づいてキー名を取得するコードをそのオブジェクトまたは一般にオブジェクトのプロトタイプに追加できます。

Object.prototype.getKeyByValue = function( value ) {
    for( var prop in this ) {
        if( this.hasOwnProperty( prop ) ) {
             if( this[ prop ] === value )
                 return prop;
        }
    }
}

そして、あなたは使用することができます

THAT.getKeyByValue(arguments.callee.caller);

ほとんどの関数が 1 つのオブジェクトにあるプロジェクトに関連するパフォーマンス テストでデバッグするために、このアプローチを 1 回使用しました。各関数の実行時間を計算するために必要な、他の方法でコード内のすべての関数または二重名に名前を付けたくありませんでした-これに加えて、関数の開始時にスタックに時間をプッシュし、終了時にポップしました。

なんで?各関数にごくわずかなコードを追加し、それらのそれぞれに同じコードを追加して、コンソールで測定と呼び出しのリストを作成します。一時オフです。

THAT._TT = [];
THAT._TS = function () {
  THAT._TT.push(performance.now());
}
THAT._TE = function () {
  var tt = performance.now() - THAT._TT.pop();
  var txt = THAT.getKeyByValue(arguments.callee.caller);
  console.log('['+tt+'] -> '+txt);
};


THAT.some_function = function (x,y,z) {
    THAT._TS();
    // ... normal function job
    THAT._TE();
}

THAT.some_other_function = function (a,b,c) {
    THAT._TS();
    // ... normal function job
    THAT._TE();
}

あまり役に立ちませんが、同様の状況で同様の問題を抱えている人に役立つかもしれません。

于 2014-08-11T11:25:39.610 に答える
0

いいえ。定義上、無名関数には がありませんname。それでも、関数式を要求したい場合: はい、それらに名前を付けることができます。

いいえ、実行時に (関数を参照する) 変数の名前を取得することはできません。

于 2012-11-07T00:26:08.873 に答える
0

arguments.calleeMDNが述べているように、非推奨です。

使用を避けarguments.callee()、すべての関数 (式) に名前を付ける必要があります。

言い換えると:

[1,2,3].forEach(function foo() {
  // you can call `foo` here for recursion
})

変数に割り当てられた無名関数の名前が必要な場合、たとえば、コードをデバッグしていて、この関数の名前を追跡したい場合、名前を 2 回指定するだけで済みます。これは一般的なパターンです。 :

var foo = function foo() { ... }

MDN docs で指定されている評価ケースを除いて、 を使用したい他のケースは考えられませんarguments.callee

于 2012-11-06T22:45:29.627 に答える