1

犬を定義しましょう:

function Dog() {}

次に、Dogをパラメーターとして渡す自己実行関数を定義しましょう。

(function(dogClassName) {

    var someServerSideLogicResolvesClassName = "dogClassName";
    //Iniate class name from the server side string
})(Dog);​

いくつかグーグルした後、私は使用する必要があることがわかりました

new window["dogClassName"]();

また

new this["dogClassName"]();

ただし、これはスコープ変数であるため、グローバル名前空間(ウィンドウなし)には存在せず、this;undefinedです。なんらかの評価を使わずにこれを達成する方法がわかりません。

4

1 に答える 1

2

そうです、グローバルに設定されていないコンストラクターにアクセスしようとしていると仮定すると、質問に対する答えは、非常に単純です。これはできません。クロージャのスコープは、さまざまなエンジンによって異なる方法で管理されます。返された関数がコンストラクターを明示的に参照していない場合、V8はコンストラクターをGCすることさえあります...
オブジェクトとして完全な外部スコープを取得する魔法の方法はありません

唯一の解決策は、名前空間オブジェクトを作成することです。

(function()
{
    var constructors = {Constructor1: function(){},
                        Constructor2: function(){}};
    return function()
    {
        var className =getClassNameViaAjax();
        if (constructors.hasOwnProperty(className))
        {
            return new constructors[className]();
        }
        if (window[className] instanceof Function)
        {//fallback
            return new window[className]()
        }
        throw className + ' Does not exist in closure, nor in global scope';
    };
}());

この質問を見てください、それは私には関連しているように見えます、あるいは重複しているようです。

躊躇する更新、ただし完全を期すため
にスコープチェーンで変数の値を参照として使用する方法は1つありますが、最も多くのEvil of Evil関数が必要eval('new '+ className + '()')です。仕様に示されているように、evalはthisバインディングを保持します。スコープチェーンを再初期化します。使用している場合を除い'strict mode';
て、コンストラクター名はajax応答から取得しており、eval悪用するのは簡単なので、これを行わないでください。これは一種の「理論的には、あなたは...」ということです。

于 2012-11-07T09:57:56.060 に答える