2009-05-28 20 views
5

¿Cómo puedo instanciar una clase introduciendo un nombre de variable? Considere este método dentro de una clase:Crear una clase de forma dinámica a través de la variable

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

Construir es un objeto que contiene un montón de cosas, pero lo más importante un "efecto" . Este efecto es el nombre de una clase de animación independiente-- se llama "MarioKartMenu".

console.log (build.effect) imprime "MarioKartMenu". Pero, por supuesto, obtengo: TypeError: El resultado de la expresión 'build.effect' [MarioKartMenu] no es un constructor.

Si Trash el dinamismo y simplemente hacer que el código como tal:

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

Funciona muy bien. ¿Es posible hacerlo dinámico como lo estoy intentando hacer?

Respuesta

5

Si la función MarioKartMenu se define en el ámbito global, se puede acceder a él por su nombre de la cadena usando:

window["MarioKartMenu"] 

Esto funciona porque todas las variables globales son propiedades del objeto window.

Teniendo en cuenta lo anterior, se puede poner en práctica lo que desea mediante el uso de:

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

perfecto, lo tenía la sensación de que sería algo como eso. Gracias. –

+0

si está dentro de una clase js puede usar como ** 'this [" MarioKartMenu "]' **. Me sorprendió esto por un tiempo y lo descubrí !! – IJas

0

Mi primera idea es utilizar el operador de JavaScript eval(), aunque entiendo que esto es una solución menos elegante. (Algo así: var animationClass = eval("new "+build.effect+"(el, build)"); aunque no estoy seguro de que sea correcto, ya que no he usado eval() así antes). La respuesta de Ayman es una variación mucho mejor en esta idea.

Mi segundo pensamiento es que MarioKartMenu no se abstrae adecuadamente. Así que crearía una clase simple a su alrededor que toma el nombre del efecto como un tercer parámetro y usa una declaración switch() para seleccionar entre todos los efectos disponibles, crea la instancia correcta y la devuelve.

+0

Buenas sugerencias. Al final no tengo idea de qué efectos habrá allí, ya que la clase que llama a las clases de animación será completamente extensible para permitir que cualquiera pueda crear y usar sus propias animaciones. Entonces una declaración de cambio no funcionaría. –

2

Basta con asignar el constructor para build.effect (no es una cadena que contiene su nombre) y debería funcionar:

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

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

También es bueno saberlo, pero una vez más, no tengo idea de lo que otros podrían nombrar a sus clases de animación, así que todavía estaría lidiando con una cadena. Sin embargo, tal vez estoy malinterpretando lo que dices. –

+1

En algún lugar los usuarios de su clase necesitan especificar qué efecto usar. ¿No pueden darle la función de constructor en lugar de una cadena con el nombre de las funciones del constructor? No estoy seguro de cómo se verá la interfaz, pero parece que un usuario haría algo como esto: var FooMenu = {...}; setEffect ("FooMenu") ;. Sugeriría que no use una cadena sino que pase FooMenu directamente: var FooMenu = {...}; setEffect (FooMenu) ;. – sth

+0

Muy válido. Voy a explorar esto. –

Cuestiones relacionadas