2012-04-19 143 views
2

我有一個構造函數,例如webapp.core.cf1或Backbone.Router。但我得到這個構造函數不作爲參考,但作爲一個字符串!我無法改變這個要求,結構。必須在字符串中。我怎樣才能從這個新的對象,例如classfun(「Backbone.Router」)?調用字符串構造函數

function classfun (cfstr) 
{ 
    ... 
    cf = new window[cfstr](); 

如果我試試這樣,我得到的錯誤:...不是一個構造函數。

爲什麼這不起作用?沒有使用eval()的替代方法嗎?

感謝很多提前

編輯

謝謝大家對你的答案!

謝謝你,Tronix117,這是問題!

謝謝你,本傑明舒爾特,功能!

+0

你能舉一個完整的例子嗎?也許,在http://jsfiddle.net上? – 2012-04-19 12:49:41

+0

以及你真正想要發生什麼的示例代碼? – Joseph 2012-04-19 12:50:23

+0

你怎麼稱呼'classfun'?你傳入什麼類型的變量? – Quentin 2012-04-19 12:51:53

回答

5

如果您在控制檯嘗試:

var A=function(a){this.test=a}; 
b = new window["A"](3); 
console.log(b.test); // return 3 

因此,這意味着,你正在試圖訪問的東西是不是在窗口的範圍,它應該是類似的東西:window.something [」 A「],如果你不知道什麼是something那麼你應該使用本傑明的功能,否則使用這個,因爲它更快。

+0

檢查窗口對象的類名屬性的好東西。這解決了我遇到的問題。謝謝! – Derek 2014-07-13 04:51:32

+0

這不是他的問題,而是在非瀏覽器的js中呢? – catbadger 2017-09-18 16:12:23

+0

@catbadger總是有一個頂級對象,它在瀏覽器環境中的非瀏覽器環境(如node.js和'window')中通常是'global'。如果你想跨越env(瀏覽器+非瀏覽器),你可以這樣做:在腳本的開始處輸入'typeof global ==='undefined'&&(window.global = window)',並使用'global'隨處可見。因此,在上面的例子中,你可以做'b = new global ['a'](3)'。 – Tronix117 2017-09-19 08:49:15

3

你可以這樣來做(如果我理解正確的話):

function getObjectByName(name) { 
    var nameParts = name.split('.'); 
    var nameLength = nameParts.length; 
    var scope = window; 

    for (var i=0; i<nameLength; ++i) { 
     scope = scope[nameParts[i]]; 
    } 

    return scope; 
} 

var ObjectClass = getObjectByName(cfstr) 
new ObjectClass(); 

仍然可以進行優化,而應該以這種方式工作。

1
ReflectUtil.newInstance = function(strClass) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    var clsClass = eval(strClass); 
    function F() { 
     return clsClass.apply(this, args); 
    } 
    F.prototype = clsClass.prototype; 
    return new F(); 
}; 

SomeClass = function(arg1, arg2) { 
    // ... 
} 

ReflectUtil.newInstance('SomeClass', 5, 7); 

這將允許您通過名稱實例化對象,並允許您根據需要傳遞參數。