2012-04-19 3 views
2

У меня есть функция конструктора, например webapp.core.cf1 или Backbone.Router. Но я получаю эту конструкторскую функцию не как ссылку, а как строку! Я не могу изменить это требование, constr. должен быть в строке. Как я могу сделать из этого новый объект, например classfun («Backbone.Router»)?Функция конструктора столбцов

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

Если я попробую это таким образом, я получу ошибку: ... не является конструктором.

Почему это не работает? Есть ли альтернативный способ без использования eval()?

Большое спасибо заранее

EDIT

Спасибо всем за ответы!

Спасибо, Tronix117, в этом была проблема !!

Спасибо, Бенджамин Шульте, за эту функцию!

+0

Можете ли вы привести полный пример? Возможно, на http://jsfiddle.net? –

+0

, а также пример кода того, что вы действительно хотите? – Joseph

+0

Как вы называете 'classfun'? Какую переменную вы переходите в нее? – Quentin

ответ

5

Если вы попробуете в консоли:

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

Так что означает, что вы пытаетесь получить доступ то, что не находится в области видимости окна, оно должно скорее быть что-то вроде этого: window.something [» A "], если вы не знаете, что такое something, тогда вы должны использовать функцию Benjamin, иначе используйте это, потому что это быстрее.

+0

Хороший материал, проверяющий объект 'window' для свойства classname. Это решило проблему, которую я имел. Благодаря! – Derek

+0

Не то, чтобы его вопрос спросил об этом, но как насчет в не-браузерах js? – catbadger

+0

@catbadger всегда есть объект верхнего уровня, он обычно «глобальный» в не-браузерах, таких как node.js и «window» в среде браузера. Если вы хотите быть кросс-env (brower + non browser), вы можете сделать это: 'typeof global === 'undefined' && (window.global = window)' в начале скрипта и использовать 'global' везде, где вам нужно. Итак, в приведенном выше примере вы делаете 'b = new global ['a'] (3)'. – Tronix117

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); 

Это позволит вам создать экземпляр объекта по его названию и позволить вам передавать параметры по мере необходимости.

Смежные вопросы