Usando jQuery $(this) con funciones de flecha ES6 (léxico este enlace)

Resuelto JRodl3r asked hace 9 años • 0 respuestas

Usar funciones de flecha de ES6 con thisenlace 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?

JRodl3r avatar Dec 28 '14 01:12 JRodl3r
Aceptado

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 thispara 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.currentTargetespecíficamente porque, incluso antes de ES6, no siempre es posible que jQuery imponga una thisfunción de devolución de llamada (es decir, si estaba vinculada a otro contexto a través de bind.

user229044 avatar Dec 27 '2014 18:12 user229044

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
});
Ryan Huang avatar Dec 10 '2015 10:12 Ryan Huang

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 ).

Tyler Liu avatar Mar 27 '2017 13:03 Tyler Liu

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.

Haritsinh Gohil avatar Jul 30 '2019 10:07 Haritsinh Gohil