2014-12-27 5 views
54

L'utilizzo di funzioni freccia ES6 con collegamento lessicale this è ottimo.

Tuttavia, mi sono imbattuto in un problema poco fa di utilizzarlo con un jQuery tipica vincolante clic:

class Game { 
    foo() { 
    self = this; 
    this._pads.on('click', function() { 
     if (self.go) { $(this).addClass('active'); } 
    }); 
    } 
} 

Utilizzando una funzione di freccia, invece:

class Game { 
    foo() { 
    this._pads.on('click',() => { 
     if (this.go) { $(this).addClass('active'); } 
    }); 
    } 
} 

E poi $(this) viene convertito in ES5 (auto = questo) chiusura del tipo.

È un modo per fare in modo che Traceur ignori "$ (this)" per il binding lessicale?

+0

Se una delle risposte qui sotto * * risposto alla tua domanda, non dimenticate di contrassegnare come accettato . Se no, forse potresti chiarire cos'altro hai bisogno di sapere? –

+0

questo sembra un perfetto esempio di quando non usare una funzione di freccia poiché '.on()' ha davvero un valore 'this' utile per te. Per me è molto più chiaro che "questo" si riferisce all'evento target piuttosto che dover passare l'evento e trovare il target manualmente. Non ho giocato molto con le funzioni di freccia, ma sembra che sarebbe confuso andare avanti e indietro con funzioni anonime. – robisrob

risposta

83

Questo non ha nulla a che fare con Traceur e disattivare qualcosa, questo è semplicemente come funziona ES6. È la funzionalità specifica che stai richiedendo utilizzando => anziché function() { }.

Se si desidera scrivere ES6, è necessario scrivere ES6 tutto il tempo, non è possibile accedere e uscire da esso su determinate righe di codice e non è possibile eliminare o alterare il modo in cui funziona =>. Anche se potessi, ti ritroverai con una versione bizzarra di JavaScript che solo tu comprendi e che non funzionerebbe mai al di fuori del tuo Traceur personalizzato, che sicuramente non è il punto di Traceur.

Il modo per risolvere questo problema particolare è non usare this per accedere all'elemento cliccato, ma invece utilizzare event.currentTarget:

Class Game { 
    foo(){ 
    this._pads.on('click', (event) => { 
     if(this.go) { 
     $(event.currentTarget).addClass('active'); 
     } 
    }); 
    } 
} 

jQuery fornisce event.currentTarget specificamente perché, anche prima ES6, non è sempre possibile per jQuery imporre una this sulla funzione callback (cioè se è stato legato a un altro contesto tramite bind.

+2

Nota, sebbene diventi solo per le chiamate delegate '.on',' this' è in realtà 'event.currentTarget'. – loganfsmyth

+0

Questa risposta è ok? Come ha osservato loganfsmyth, 'this' ==' event.currentTarget'. No? –

+1

@ LéonPelletier No. 'this' e' event.currentTarget' sono gli stessi, a meno che 'questo' sia associato all'ambito di inclusione, come con una funzione freccia ES6. – meagar

29

vincolante evento

$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 
}); 
+0

L'associazione degli eventi è migliore per noi;) – rflmyk

4

(Questa è una risposta che ho scritto per un'altra versione di questa domanda, prima di imparare che fosse un duplicato di questa domanda. Penso che la risposta riunisca abbastanza chiaramente le informazioni, quindi ho deciso di aggiungerla come wiki di una comunità, anche se è in gran parte solo fraseggio delle altre risposte.)

Non è possibile. Questo è metà del punto delle funzioni di freccia, si chiude su this invece di avere il proprio che è impostato da come vengono chiamati. Per il caso d'uso nella domanda, se si desidera impostare this da jQuery quando si chiama il gestore, il gestore deve essere una funzione function.

Ma se avete un motivo per l'utilizzo di una freccia (forse si vuole utilizzare this per quello che significa fuori dalla freccia), è possibile utilizzare e.currentTarget invece di this Se ti piace:

class Game { 
    foo(){ 
    this._pads.on('click', e => {     // Note the `e` argument 
     if(this.go) { 
     $(e.currentTarget).addClass('active');  // Using it 
     } 
    }); 
    } 
} 

Il currentTarget sull'oggetto evento è uguale a quello che jQuery imposta this su quando chiama il gestore.

8

Un altro caso

La risposta in alto è corretta e l'ho votato.

Tuttavia, v'è un altro caso:

$('jquery-selector').each(() => { 
    $(this).click(); 
}) 

potrebbe essere fissato come:

$('jquery-selector').each((index, element) => { 
    $(element).click(); 
}) 
+5

Non esiste una risposta accettata. E, secondo le scadenze, non c'è mai stato. –