Usando jQuery $(this) con funciones de flecha ES6 (léxico este enlace)
Usar funciones de flecha de ES6 con this
enlace léxico es genial.
Sin embargo, hace un momento me encontré con un problema al usarlo con un enlace de clic típico de jQuery:
class Game {
foo() {
self = this;
this._pads.on('click', function() {
if (self.go) { $(this).addClass('active'); }
});
}
}
Usando una función de flecha en su lugar:
class Game {
foo() {
this._pads.on('click', () => {
if (this.go) { $(this).addClass('active'); }
});
}
}
Y luego $(this)
se convierte al cierre de tipo ES5 (self = this).
¿Existe una forma de hacer que Traceur ignore "$(this)" para la vinculación léxica?
Esto no tiene nada que ver con Traceur y apagar algo; Así es simplemente como funciona ES6. Es la funcionalidad específica que estás solicitando al usar =>
en lugar de function () { }
.
Si desea escribir ES6, debe escribir ES6 todo el tiempo. No puedes entrar y salir de él en ciertas líneas de código, y definitivamente no puedes suprimir o alterar la forma en que =>
funciona. Incluso si pudieras, terminarías con una versión extraña de JavaScript que solo tú entiendes y que nunca funcionaría correctamente fuera de tu Traceur personalizado, lo cual definitivamente no es el objetivo de Traceur.
La forma de resolver este problema en particular no es utilizar this
para obtener acceso al elemento en el que se hizo clic, sino utilizar event.currentTarget
:
Class Game {
foo(){
this._pads.on('click', (event) => {
if(this.go) {
$(event.currentTarget).addClass('active');
}
});
}
}
jQuery proporciona event.currentTarget
específicamente porque, incluso antes de ES6, no siempre es posible que jQuery imponga una this
función de devolución de llamada (es decir, si estaba vinculada a otro contexto a través de bind
.
Enlace de eventos
$button.on('click', (e) => {
var $this = $(e.currentTarget);
// ... deal with $this
});
Bucle
Array.prototype.forEach.call($items, (el, index, obj) => {
var $this = $(el);
// ... deal with $this
});
Otro caso
La respuesta de Meagar es correcta y la he votado a favor.
Sin embargo, hay otro caso:
$('jquery-selector').each(() => {
$(this).click();
})
Podría arreglarse como:
$('jquery-selector').each((index, element) => {
$(element).click();
})
Este es un error histórico en jQuery que coloca el índice , en lugar del elemento , como primer argumento:
.cada uno (función)
Tipo de función
:Function( Integer index, Element element )
una función que se ejecutará para cada elemento coincidente.
Ver: https://api.jquery.com/each/#each-function
También se aplica a .map( function )
y .filter( function )
.
Como dijo Meager en su respuesta a esta misma pregunta, si desea escribir ES6, debe escribir ES6 todo el tiempo .
entonces, si está usando la función de flecha de ES6:, (event)=>{}
entonces debe usarla $(event.currentTarget)
en lugar de $(this)
.
También puedes usar una forma más agradable y limpia de usar currentTarget como ({currentTarget})=>{}
,
Class Game {
foo(){
this._pads.on('click', ({currentTarget}) => {
if(this.go) {
$(currentTarget).addClass('active');
}
});
}
}
Originalmente, esta idea fue comentada por Rizzi Frank en la respuesta de Meagar, la sentí útil y creo que no todas las personas leerán ese comentario, así que lo escribí como esta otra respuesta.