2012-08-19 3 views
1

J'ai regardé d'autres exemples en ligne, mais ils n'ont pas fonctionné.Instantaition dynamique en JavaScript

Alors ...

Je suis en train de mettre en œuvre le « modèle de décorateur » classique de « Head First » en JavaScript ... et je suis vraiment proche.

le cas suivant: "CLASSES"

// "CLASSES": BEVERAGES 
function DarkRoast(){ 
    this.cost = 1.00; 
    this.description = "Dark Roast"; 
}; 

// DECORATORS: CONDIMENTS 
function Milk(beverage){ 
    var instance = beverage; 
    beverage.cost = function(){ 
     return instance.cost + 0.25; 
    }; 
    beverage.description = functionn(){ 
     return instance.description + ', Milk'; 
    }; 
}; 

QUESTION: Comment puis-je instancier "Milk" dynamique de la fonction suivante?

function appendCondiment(className, beverage) { 
    /* Needs to do this, but dynamically: 
     var instance = new Milk(beverage); */ 

    // This fails (of course) 
    var instance = new window[className].call(beverage); 
} 
+1

Vos cours sont des fonctions globales? C'est une mauvaise idée ... l'utilisation de variables globales devrait être minimisée. Définissez un espace de noms 'MYAPP.classes', puis' var Milk = MYAPP.classes ["Milk"] '... –

+0

Vous écrasez la propriété numérique' .cost' avec une méthode '.cost'. (Idem pour '.description') Vous ne pouvez pas avoir deux propriétés du même nom sur le même objet. –

+0

'new' est inutile pour' Milk'. Il modifie 'boisson 'au lieu de' ceci'. – pimvdb

Répondre

0

Vous devez:

var instance = new window[className](beverage); 
+0

Bien que cela ait instancié l'instance. L'appel de COST sur la boisson échoue. Donc, cette solution ne fonctionnera pas. –

+0

@PrisonerZERO Il échoue parce que votre méthode '.cost' a écrasé la propriété numérique' .cost'. Vous ne pouvez pas avoir deux propriétés du même nom sur le même objet. –

+0

@ ŠimeVidas Bon point ... merci. –

0

Que diriez-vous:

var DarkRoast = function() { 
    this.cost = 1.00; 
    this.description = 'Dark Roast'; 
}; 

var condiments = { 
    milk: { 
     cost: 0.25; 
     description: 'Milk' 
    }, 
    cream: { 
     cost: 0.3, 
     description: 'Cream' 
    } 
}; 

var appendCondiment = function (condimentName, beverage) { 
    var condiment = condiments[ condimentName ]; 
    beverage.cost += condiment.cost; 
    beverage.description += ', ' + condiment.description; 
}; 

Utilisation:

var bev = new DarkRoast(); 
appendCondiment('milk', bev); 

bev.cost // 1.25 
bev.description // 'Dark Roast, Milk' 

BTW, envisager d'avoir DarkRoast hériter d'une classe Beverage, puis définir une méthode appendCondiment à Beverage.prototype. Ensuite, vous seriez en mesure d'écrire ceci:

var bev = new DarkRoast(); 
bev.appendCondiment('milk'); 

qui est plus lisible.

+0

Pourquoi arrêter là? Il me semble que "dark rôti" devrait être un attribut d'une "classe" Beverage, donc 'var bev = new Beverage ('rôti foncé')' et ainsi de suite. – RobG

+0

@RobG Oui, c'est logique. –

Questions connexes