2012-04-07 12 views
1

私は"AppNamespace.SomeObject.ClassName"などの刺青があり、文字列が実際のコンストラクタ関数を表していることを知っていますが、声明の中でvar foo = new AppNamespace.SomeObject.ClassNameのように? evalを伴うまたは文字列とループを分割する必要がありません、より良い解決策があるかどうJavaScriptでの名前空間、文字列表現のコンストラクタ関数を取得する最も良い方法

var parts = "AppNamespace.SomeObject.ClassName".split(".") 
var foo = new (window[parts[0]][parts[1]][parts[2]]) 

が、私は思ったんだけど:よう

var s = "AppNamespace.SomeObject.ClassName" 
var foo = new (eval(s)) 

か何かを:

私が行うことができますその部分を通して。誰にもアイデアはありますか?そうでない場合は、私が提案した2つのソリューションに基づいて、それぞれの賛否両論は何ですか?

答えて

2

あなたは...

var obj = new ('AppNamespace.SomeObject.ClassName' 
       .split('.') 
       .reduce(function(object, key) { 
          return object[key]; 
         }, window)); 

jsFiddleを行うことができます。

古いブラウザでは、reduce()をシムできます。

このコードは、期間(.)によって文字列を分割した後、左から右への各反復処理、開始オブジェクトとしてwindow始まる(そうでない場合、それを変更し)、それがで到着するまで、各サブプロパティを取得します右端(あなたの例ではClassName)。

new (...)は、このオブジェクトをインスタンス化します。

あなたは、再利用可能な機能としてそれを書くことができます...

var getObjectByString = function(string, baseObject, delimiter) { 
    // Only checks for string primitives, but that's OK for this example. 
    if (typeof string !== 'string') { 
     throw new TypeError('First argument is required and must be a string.'); 
    } 

    baseObject = baseObject || window; 
    delimiter = delimiter || '.'; 

    return string 
      .split(delimiter) 
      .reduce(function(object, key) { 
         return object[key]; 
        }, baseObject)); 
}; 
+0

Array#reduceは、現在のブラウザ環境では利用可能な在庫が限られています。https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/Array/Reduce – dfreeman

+0

@dfreemanはい、どんなブラウザでも簡単にシミングできます。 – alex

+0

そして、それは価値があるため、私のアプリケーションでunderscore.jsを使用しています –

3

evalは悪です。ループオプションを使用します。

ループオプションの良い点は、オブジェクトが参照渡しされることです。だから、:

function getObjectFromString(str) { 
    var parts = str.split("."), curr = window, last = parts.pop(), p; 
    while(p = parts.shift()) curr = curr[p]; 
    return curr[last]; 
} 

この機能はあなたの例では、あなたが探しているコンストラクタで対象オブジェクトを返します。

var s = "AppNamespace.SomeObject.ClassName"; 
var foo = new (getObjectFromString(s)); 
+0

、そこevalは悪である理由の理由がありますが、私が知っている文字列を変換することは確かにそれらの一つではないオブジェクトに安全です右? –

関連する問題