2009-05-28 6 views
5

Как я могу создать экземпляр класса, указав имя переменной? Рассмотрим этот метод внутри класса:Динамическое создание класса с помощью переменной

animate: function(el, build) { 
     console.log(build.effect); 
     var animationClass = new build.effect(el,build); 
}, 

Сложение является объект, содержащий много вещей, но самое главное, «следствием» . Этот эффект является именем независимого класса анимации - один называется «MarioKartMenu».

console.log (build.effect) печатает «MarioKartMenu». Но, конечно, я получаю: TypeError: Результат выражения 'build.effect' [MarioKartMenu] не является конструктором.

Если я мусор динамизм и просто сделать код как таковой:

animate: function(el, build) { 
     var animationClass = new MarioKartMenu(el,build); 
    }, 

Он работает просто отлично. Можно ли сделать его динамичным, как я пытаюсь сделать?

ответ

5

Если функция MarioKartMenu определена в глобальном масштабе, вы можете получить доступ к нему по имени строки с помощью:

window["MarioKartMenu"] 

Это работает, потому что все глобальные переменные свойства window объекта.

Учитывая вышесказанное, вы можете осуществить то, что вы хотите с помощью:

var menuConstructor = window[build.effect]; 
var animationClass = new menuConstructor(el, build); 
+0

Отлично, у меня было чувство, что это будет выглядеть примерно так. Спасибо. –

+0

, если он находится в классе js, вы можете использовать как ** 'this [" MarioKartMenu "]' **. Я был поражен этим некоторое время и понял это! – IJas

0

Моя первая мысль заключается в использовании eval() оператора в JavaScript, хотя я понимаю, что это меньше, чем элегантное решение. (Soemthing вот так: var animationClass = eval("new "+build.effect+"(el, build)");, хотя я не уверен, что это правильно, поскольку я не использовал eval(), как это раньше.). Ответ Аймана - намного лучшая вариация этой идеи.

Моей второй мыслью является то, что MarioKartMenu не является соответствующим образом абстрагированным. Поэтому я бы построил вокруг него простой класс, который использует название эффекта в качестве третьего параметра и использует оператор switch() для выбора среди всех доступных эффектов, создает правильную версию и возвращает ее.

+0

Хорошие предложения. В конце концов, я понятия не имею, какие эффекты будут там, поскольку класс, вызывающий классы анимации, будет полностью расширяемым, чтобы позволить кому-либо создавать и использовать свои собственные анимации. Поэтому оператор switch не будет работать. –

2

Просто назначить конструктор для build.effect (а не строка, содержащая его имя), и это должно работать:

animate = function(el, build) { 
    var animationClass = new build.effect(el,build); 
} 
// ... 

b = ...; 
b.effect = MarioKartMenu; 
animate(e, b); 
+0

Также хорошо знать, но еще раз, я понятия не имею, что другие могут назвать своими классами анимации, поэтому я все равно буду иметь дело со строкой. Возможно, я не понимаю, что вы говорите. –

+1

Где-то пользователи вашего класса должны указать, какой эффект использовать. Разве они не могут дать вам функцию-конструктор вместо строки с именем функции-конструктора? Я не уверен, как будет выглядеть интерфейс, но похоже, что пользователь сделал бы что-то вроде этого: var FooMenu = {...}; setEffect ("FooMenu") ;. Я бы предложил не использовать строку, но передать FooMenu напрямую: var FooMenu = {...}; setEffect (FooMenu) ;. – sth

+0

Очень актуально. Я собираюсь изучить это. –

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