Javascript portée addEventListener et ce
Je suis un développeur C# à expérimenter avec JavaScript et je vais essayer d'obtenir ma tête autour de la portée 🙂
J'ai le code suivant qui contient un addEventListener
dans laquelle je veux utiliser un champ de mon objet:
(function(window) {
function Keyboard() {
this.keys = {};
}
Keyboard.prototype.handle_keydown = function(args) {
this.keys[args.keyCode] = true;
}
Keyboard.prototype.listen = function() {
window.addEventListener('keydown', this.handle_keydown);
}
app.util.keyboard = new Keyboard();
})(window);
Je voudrais utiliser le tableau de clés dans mon virage, mais comprenez que je ne peux pas accéder est par l'utilisation de cela, parce que c'est la fenêtre dans ce contexte (correct?).
Si je l'ai changer pour
app.util.keyboard.keys[args.keyCode] = true;
cela fonctionne, mais je ne suis pas sûr que c'est un bon moyen pour résoudre ce problème.
J'ai trouvé cette question, ce qui semble assez similaire, mais Im pas sûr de savoir comment je peux l'adapter dans mon exemple.
Merci pour votre aide!
- Avez-vous d'ajouter les fonctions par l'intermédiaire de prototype, pouvez-vous placer dans la fonction de Clavier à la place?
- Est-il une raison pour laquelle vous êtes à l'aide d'un auto-exécution de la fonction?
- Je voudrais appeler les écouter fonction dans une autre fonction que lorsque je crée le Clavier, donc je pense que je dois?
- Je pense que je vais le faire aussi garantir mes variables de l'étendue du Clavier de "classe"?
- C'est vrai, et qui semble la manière la plus responsable pour l'utiliser il suffit de se demander.
Vous devez vous connecter pour publier un commentaire.
Que peu de choses:
La plupart des gens suggèrent quelque chose comme
var self = this
parce qu'il est rapide et facile.Mais
var self = this
ne pas séparer les objet de vue entièrement à partir de la vue logique, qui, à partir d'un cadre plus formel de C# arrière-plan et en regardant ton code, ça sonne comme quelque chose que vous voulez faire.Afin d'avoir le rappel s'exécute que lorsque l'événement est déclenché, envelopper le gestionnaire dans une fonction, de sorte qu'il est évalué tout de suite, mais n'est exécutée que si un
keydown
événement se déclenche (voir le code ci-dessous).Compréhension de la portée en JS: Quel que soit le contexte d'exécution est, est également le champ d'application actuel. Votre auditeur a été ajouté dans une méthode (appelée
listen
) surKeyboard.prototype
, mais lekeydown
événement est en fait tiré surwindow
-- le gestionnaire est en cours d'exécution dans un contexte différent de celui où il a été défini; il est en cours d'exécution dans le contexte de ce qui est en l'invoquant, dans ce cas,window
, il est donc portée àwindow
à moins que vous lier à un autre objet, parbind
ouapply
lorsqu'il est défini.Dans votre code,
window
est le point de vue d'un utilisateur d'interagir avec, etKeyboard
est que de la vue du contrôleur. Dans les motifs MVC comme ce que vous êtes probablement habitué à en C#/.NET, points de vue ne pas dire à eux-mêmes quoi faire quand les choses se passent, les contrôleurs de vues dire quoi faire. Donc, si vous assignez une référence au contrôleur en utilisantvar self = this
comme beaucoup, le point de vue de la gestion elle-même, mais uniquement ce que le gestionnaire pourkeydown
événements. C'est incohérent, et il est devenu difficile à gérer dans un projet de grande envergure.Une solution:
Une meilleure solution:
La meilleure solution (jusqu'à ES6
class
est prêt):.bind()
est compatible avec ECMAScript 5+; si vous avez besoin d'une solution pour les anciens navigateurs, Mozilla a publié une excellente alternative à.bind()
à l'aide defunctions
et.call()
:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind
Edit: Voici ce que votre instancié
keyboard
objet à l'aide de cette nouvelle solution modulaire:removeEventListener
? J'ai besoin d'un nom de fonction.. ho utiliser lebind
chose?addEventListener('keydown', handler)
au lieu deaddEventListener('keydown', function () {})
. De cette façon, vous pouvez par la suite l'enlever par référence.Comment ce code fonctionne:
this
variable.this
points de l'objet dom, tandis queself
points de clavier objet.event
comme un paramètre que nous passons à la fonction de membre du clavier de l'objet.Comment sur