2009-09-02 8 views
11

Sto provando ad accedere alle variabili membro di una classe prototipo in JavaScript in un gestore eventi - qualcosa che in genere utilizzerei la parola chiave "this" per (o "quello" [copia di questo] nel caso di gestori di eventi). Inutile dire che mi trovo nei guai."questa" parola chiave nei metodi evento quando si utilizza l'oggetto prototipo JavaScript

Prendiamo, per esempio, questo frammento di codice HTML:

<a id="myLink" href="#">My Link</a> 

E questo codice JavaScript:

function MyClass() 
{ 
    this.field = "value" 
    this.link = document.getElementById("myLink"); 
    this.link.onclick = this.EventMethod; 
} 

MyClass.prototype.NormalMethod = function() 
{ 
    alert(this.field); 
} 

MyClass.prototype.EventMethod = function(e) 
{ 
    alert(this.field); 
} 

un'istanza di un oggetto MyClass e chiamando NormalMethod funziona esattamente come mi aspettavo che (avviso che dice " valore "), ma facendo clic sul collegamento si ottiene un valore indefinito perché la parola chiave" this "ora fa riferimento al target dell'evento (l'elemento HTML anchor).

Sono nuovo al prototipo JavaScript stile, ma in passato, con chiusure, ho semplicemente fatto una copia di "questo" nel costruttore:

var that = this; 

E poi ho potuto accedere ai membri variabili nei metodi evento tramite l'oggetto "that". Non sembra funzionare con il codice prototipo. C'è un altro modo per raggiungere questo obiettivo?

Grazie.

+0

Si riferisce alla libreria Prototype o meglio dritti classi prototipo JavaScript? –

+3

Rispondere con tre anni di ritardo :) Ma per i posteri: mi riferivo a classi prototipo dritte di JavaScript. – Michael

+0

Possibile duplicato di [Come accedere al corretto 'this'/contesto all'interno di un callback?] (Http://stackoverflow.com/q/20279484/1048572)? – Bergi

risposta

9

tuo "that=this" chiusura idioma è ancora applicabile:

function MyClass() 
{ 
    ... 

    var that = this; 
    this.link.onclick = function() { 
     return that.EventMethod.apply(that, arguments); 

     // that.EventMethod() works too here, however 
     // the above ensures that the function closure 
     // operates exactly as EventMethod itself does. 

    }; 
} 
5

Si dovrebbe cercare

this.link.onclick = this.EventMethod.bind(this); 
13

È necessario:

this.link.onclick = this.EventMethod.bind(this); 

... 'bind' fa parte di Prototype, e restituisce una funzione che chiama il tuo metodo con "questo" impostato correttamente.

+0

In che modo "onclick" ottiene l'accesso all'interfaccia evento? – Karl

+0

@Karl Con "accesso all'interfaccia evento" intendi "ricevere l'oggetto evento come argomento"? Il metodo 'bind' ** restituisce una funzione ** (con un fisso' this'), quindi 'onclick = this.EventMethod' è fondamentalmente la stessa di' onclick = this.EventMethod.bind (this) '.In entrambi i casi, si memorizza una funzione nella proprietà 'onclick'; sono identici in termini di come vengono gestiti i loro argomenti. Se la tua domanda riguarda in generale il modo in cui gli argomenti vengono passati alle funzioni dell'ascoltatore, è una domanda piuttosto diversa da quella che viene posta qui, e dovresti fare una nuova domanda. – apsillers

0

Come indicato in precedenza, l'utilizzo del binding che fa parte della libreria Prototype è un modo pulito per risolvere questo problema. Questa domanda è un duplicato di un altro SO domanda cui risponde qui con l'attuazione del metodo bind senza includere l'intera libreria prototipo:

https://stackoverflow.com/a/2025839/1180286

+0

Questa domanda utilizza JQuery. Preferirei vedere una semplice domanda/risposta JavaScript come standard. –

Problemi correlati