L'utilisation des fonctions fléchées ES6 avec la liaison lexicale this
est excellente.
Cependant, j'ai rencontré un problème il y a un moment, je l'utilisais avec une liaison de clic jQuery typique:
class Game {
foo() {
self = this;
this._pads.on('click', function() {
if (self.go) { $(this).addClass('active'); }
});
}
}
En utilisant une fonction de flèche à la place:
class Game {
foo() {
this._pads.on('click', () => {
if (this.go) { $(this).addClass('active'); }
});
}
}
Et puis $(this)
est converti en fermeture de type ES5 (self = this).
Est-ce qu’une façon de faire en sorte que Traceur ignore "$ (this)" pour la liaison lexicale?
Cela n'a rien à voir avec Traceur et désactiver quelque chose, c'est simplement ainsi que fonctionne ES6. C'est la fonctionnalité spécifique que vous demandez en utilisant =>
Au lieu de function () { }
.
Si vous voulez écrire ES6, vous devez écrire tout le temps, vous ne pouvez pas activer ou désactiver cette fonction sur certaines lignes de code, et vous ne pouvez absolument pas supprimer ou modifier le fonctionnement de =>
. Même si vous le pouviez, vous vous retrouveriez avec une version bizarre de JavaScript que vous seul comprenez et qui ne fonctionnerait jamais correctement en dehors de votre Traceur personnalisé, ce qui n'est certainement pas le but de Traceur.
La façon de résoudre ce problème particulier n’est pas d’utiliser this
pour accéder à l’élément cliqué, mais d’utiliser event.currentTarget
:
Class Game {
foo(){
this._pads.on('click', (event) => {
if(this.go) {
$(event.currentTarget).addClass('active');
}
});
}
}
jQuery fournit event.currentTarget
spécifiquement parce que, même avant ES6, il n’est pas toujours possible pour jQuery d’imposer un this
à la fonction de rappel (c’est-à-dire si elle était liée à un autre contexte via bind
.
Liaison d'événement
$button.on('click', (e) => {
var $this = $(e.currentTarget);
// ... deal with $this
});
Loop
Array.prototype.forEach.call($items, (el, index, obj) => {
var $this = $(el);
// ... deal with $this
});
La réponse du haut est correcte et je l’ai votée à la hausse.
Cependant, il y a un autre cas:
$('jquery-selector').each(() => {
$(this).click();
})
Peut être corrigé comme:
$('jquery-selector').each((index, element) => {
$(element).click();
})
(C’est une réponse que j’ai écrite pour une autre version de cette question, avant d’apprendre que c’était une copie de cette question. Je pense que la réponse rassemble assez clairement les informations, aussi j’ai décidé de l’ajouter comme wiki de communauté, bien que c'est en grande partie une formulation différente des autres réponses.)
Tu ne peux pas. C'est la moitié du point des fonctions de flèche, elles se ferment au-dessus de this
au lieu d'avoir leur propre fonction définie par la façon dont elles sont appelées. Pour le cas d'utilisation de la question, si vous souhaitez que this
soit défini par jQuery lors de l'appel du gestionnaire, le gestionnaire doit être une fonction function
.
Mais si vous avez une raison d'utiliser une flèche (peut-être que vous voulez utiliser this
pour ce que cela signifie en dehors de la flèche), vous pouvez utiliser e.currentTarget
au lieu de this
si vous aimez:
class Game {
foo(){
this._pads.on('click', e => { // Note the `e` argument
if(this.go) {
$(e.currentTarget).addClass('active'); // Using it
}
});
}
}
Le currentTarget
sur l'objet d'événement est identique à ce que jQuery définit this
lorsque vous appelez votre gestionnaire.
Comme maigre dans sa réponse à la même question si vous voulez écrire ES6, vous devez écrire ES6 tout le temps ,
donc si vous utilisez la fonction de flèche de ES6: (event)=>{}
, vous devez alors utiliser $(event.currentTarget)
au lieu de $(this)
.
vous pouvez également utiliser un moyen plus simple et plus propre d’utiliser currentTarget comme ({currentTarget})=>{}
,
Class Game {
foo(){
this._pads.on('click', ({currentTarget}) => {
if(this.go) {
$(currentTarget).addClass('active');
}
});
}
}
à l'origine, cette idée a été commentée par rizzi frank dans la réponse de @ Meager, et je la sentais utile et je pense que tout le monde ne lira pas ce commentaire, je l'ai donc écrit comme une autre réponse.