L'ajout de fonctions d'écouteur à l'objet JavaScript
J'ai le code suivant qui définit un Car
. Chaque Car
a une couleur, avec une setColor(color)
fonction. Je veux ajouter des fonctions d'écouteur qui sont appelés à chaque fois que setColor(color)
est appelé, et je veux être en mesure de virer ces fonctions d'écouteur à chaque fois que je veux. Est-ce une solution? Est-il le moyen le plus propre?
function Car() {
this._color = 'red';
this._callbacks = {};
this.setColor = function(color) {
this._color = color;
console.log(">>> set car color to " + color);
if (this._callbacks['setColor']) {
this._callbacks['setColor']();
}
};
this.addListener = function(functionName, handler) {
if (this._callbacks[functionName]) {
var oldCallback = this._callbacks[functionName];
this._callbacks[functionName] = function() {
oldCallback();
handler();
}
} else {
this._callbacks[functionName] = function() {
handler();
}
}
};
}
var car = new Car();
car.setColor('blue');
car.addListener('setColor', function() { console.log("This is listener # 1"); });
car.setColor('green');
car.addListener('setColor', function() { console.log("This is listener # 2"); });
car.setColor('orange');
De sortie:
>>> setColor to blue
>>> setColor to green
This is listener # 1
>>> setColor to orange
This is listener # 1
This is listener # 2
OriginalL'auteur Andrew | 2012-08-21
Vous devez vous connecter pour publier un commentaire.
Je pense qu'un tableau pour stocker les auditeurs seraient un plus propre approche. Aussi, vous devez utiliser le prototype de l'objet, ou de faire le semi-privées des propriétés réelles des variables privées.
Ou:
Voir les Avantages de l'utilisation de prototype, vs la définition de méthodes directement dans le constructeur? ou Déclarant le javascript méthode de l'objet en fonction de constructeur vs en prototype. Dans le premier exemple, les propriétés de l'objet sont publiques (seulement le trait de soulignement indiqué qu'ils ne doivent pas être utilisés à partir de l'extérieur) - dans le deuxième exemple, j'ai utilisé des variables locales dans l'étendue du constructeur, et ils ne sont accessibles qu'aux deux privilégiée méthodes. (Assez de mots à la mode à google 😉
La réponse par @Utkanos était bon aussi, mais la deuxième option qui est donné ici est la solution que j'ai fini de l'utiliser. Cela se débarrasse de la semiprivateness de mes variables
color
etcallbacks
et met les fonctions de rappel dans un tableau au lieu d'une fermeture.OriginalL'auteur Bergi
Quelque chose comme ça, peut-être.
Note que vous attribuez prototype-esq méthodes pour les instances plutôt que de le prototype - le lieu pour la de lhéritage, des fonctionnalités réutilisables. L'héritage est également plus rapide en termes de performances.
Car.{method}
fonctions d'unthis.{method}
fonction? (En d'autres termes, remplaçant les trois instances de "Voiture" à "ce" à l'intérieur de laCar
corps de la fonction.Pourquoi avez-vous fait les auditeurs statique? Je ne pense pas que ce soit une bonne idée.
le prototype est l'endroit pour être héritées, des fonctionnalités réutilisables. La façon dont vous avez fait cela va fonctionner, mais en fonction d'instance méthodes sont légèrement plus lentes (délivré, vous devez avoir beaucoup de lourde les méthodes de remarquer la différence) et cela signifie qu'ils sont propres propriétés (de sorte qu'ils seront énumérable) de l'exemple, plutôt que d'hériter.
pourquoi donc? Vous ne m'étendrai pas. Semble fonctionner OK. L'une, statique de la place pour les auditeurs pour toutes les méthodes. Fonctionne très bien avec plusieurs instances. jsfiddle.net/akxVD/1 Heureux d'être corrigé.
Oui, il fonctionne, mais je ne pense pas qu'il est destiné. La rupture de la Fpo fonctionnalité aurait besoin d'au moins un commentaire sur ce
OriginalL'auteur Utkanos
Si cela fonctionne pour vous, alors je ne vois aucune raison de ne pas aller avec elle. Quelques réflexions sur cette approche:
addListener
méthode de prendre un objet de contexte et necallback.call(context)
. Si vous ne vous inquiétez pas à ce sujet, alors pas besoin de s'inquiéter à ce sujet.callback(this, this._color)
?Une autre chose à considérer est l'aide de
Object.defineProperty
, mais c'est un peu plus stylistique choix.OriginalL'auteur Matt Greer