7

コレクション/配列に格納されたいくつかの関数があり、再入力せずにキー (関数名) を取得したいと考えています。アクセスするための短い方法はありますか?

var functions_collection = {
    "function_x": function() {
        var name = "function_x";
        // name = this.key; <- how to get the key/function-name "function_x"?

        // some more code like:
        $(".function_x .button").val();

        alert(name);
    }
}

編集: 関数自体の中で "function_x" を再入力することを避け、this.key のように呼び出すことを好みます。

変な話題ですみません、よろしくお願いします!

解決策:多くの良い答えがありますが、私はこれを探していました:

Object.keys(this)
4

5 に答える 5

3

ここに行く方法はいくつかあります。良いアイデアもあれば、そうでないものもあります。

まず、いくつかの悪い考え

  1. 悪いアイデア:arguments.callee.name

    これは、あなたが求めるものに最も直接的に変換されます。arguments.callee現在使用している関数への参照です。ただし、これは悪い習慣と見なされている ため、よほどの理由がない限り使用を避ける必要があります。

  2. 悪い考え:カリー化

    関数を構築した後、独自の名前をパラメーターとしてバインドします。

    var functions_collection = {
        "function_x": function(name) {
            alert(name);
        },
        //more functions
    };
    for (var name in functions_collection) {
        if (typeof functions_collection[name] === "function") {
            functions_collection[name] = 
                functions_collection[name].bind(functions_collection, name);
        }
    }
    

    カリー化は JavaScript の多くのことに役立ち、多くの状況で優れたアイデアです。ただし、ここにはありません。その理由を以下で説明します。

  3. 悪い考え:ローカル パラメーターを使用し、それを含むオブジェクトを反復処理します。

    var functions_collection = {
         "function_x": function(name) {
             alert(name);
         },
         //more functions
    };
    for (var name in functions_collection) {
        if (typeof functions_collection[name] === "function") {
            functions_collection[name](name);
        }
    }
    

    もちろん、これに関する明らかな問題は、コレクション内のすべての関数を一度に呼び出したくない場合があることです。より根本的な問題は、危険なほど密結合の傾向が続いていることです。これは悪いことであり、潜在的に非常に悪いことであり、あらゆる種類の頭痛の種になる可能性があります.

今、「正しい」方法

アプローチ全体を変更します。HTML からクラス名をリサイクルしようとするのは忘れてください。シンプルにしてください。

  1. 良いアイデア:ローカル変数を使用する

    関数の名前を誰が気にしますか? 触れさせたい HTML クラスがわかっている場合は、そのようにコーディングしてください。

    var functions_collection = {
        "function_x": function() {
             var name = "function_x"; //or "button" or any other class name
             alert(name);
         },
         //more functions
    };
    functions_collection.function_x();
    
  2. 良いアイデア:パラメータを渡す

    あなたはすでに関数を呼び出していますよね?したがって、必要な名前にアクセスできるコードが既にどこかにある可能性があります。

    var functions_collection = {
        "function_x": function(name) {
             alert(name);
         },
         //more functions
    };
    
    functions_collection.function_x("function_x"); //or any other class name
    

    function_x関数名と一致しない場合でも、HTML の任意のクラスで使用できるようになりました。

    functions_collection.function_x("function_y");
    functions_collection.function_x("class_z");
    functions_collection.function_x("button");
    

    最も単純なものを最後に保存しました。それが理にかなっている場合、「賢く」しようとすることで間違いを犯していると思うからです。あなたのアプローチには重大なリスクがあり、見返りはそれだけの価値はありません。

なぜ悪いアイデアは悪く、良いアイデアは良いのか

オプション以外に、arguments.callee.nameこの場合の 2 と 3 が悪い理由は密結合です。function_xの構造に結合していますfunctions_collection。動作を変数名に結合しています。そして最悪なのは、JS 変数を HTML 要素のクラス名に結合していることです。これにより、コードが非常に壊れやすくなり、何かを変更したい場合 (および変更する場合) は、傷の世界に備える必要があります。

たとえば、HTML を再編成するとどうなるでしょうか。JS の構造は HTML/CSS のクラスと一致する必要があるため、ページが壊れる可能性があります。名前を変更するか書き直す必要がfunctions_collectionあり、それ以外の場合は、既存の JS を中心に新しい HTML を慎重に計画する必要があります。

JS minifier を使用したい場合はどうなりますか? 場合によりますが、オブジェクト リテラルのメンバー名を変更できるようにすると、すべてが完全に壊れてしまい、「良い」アイデアの 1 つからやり直す必要があります。

では、この柔軟性のなさと引き換えに、あなたは何を得るのでしょうか? 各関数の先頭に余分な行を保存します。それだけの価値はありません、私見。弾丸をかむだけで、シンプルに保ちます。

于 2013-06-04T19:55:57.103 に答える
3

オブジェクトのキーの名前を取得するにはObject.getOwnPropertyNames(this)、新しいブラウザでは単に または を使用できます。これにより、オブジェクトが持つObject.keys(this)すべてのキーと任意のキーの配列が取得されます。this

var functions_collection = {
    function_x: function() {
        var name = Object.keys(this);
        console.log(name);
    }
}

フィドル

于 2013-06-04T19:13:27.287 に答える