2010-10-25 5 views
5

Sto attraversando un periodo davvero difficile per descrivere i prototipi in JavaScript.Impossibile utilizzare i metodi "di classe" per i callback in JavaScript

In precedenza ho avuto problemi a chiamare qualcosa di simile:

o = new MyClass(); 
setTimeout(o.method, 500); 

e mi hanno detto che potrei risolvere il problema utilizzando:

setTimeout(function() { o.method(); }, 500); 

E questo funziona. Ora ho un problema diverso, e ho pensato di poterlo risolvere allo stesso modo, semplicemente inserendo una funzione anonima. Il mio nuovo problema è questo:

MyClass.prototype.open = function() { 
    $.ajax({ 
     /*...*/ 
     success: this.some_callback, 
    }); 
} 

MyClass.prototype.some_callback(data) { 
    console.log("received data! " + data); 
    this.open(); 
} 

Ho constatato che all'interno del corpo del MyClass.prototype.some_callback la parola this non si riferisce all'istanza di MyClass quale il metodo è stato chiamato, ma piuttosto quello che sembra essere il jQuery richiesta ajax (è un oggetto che contiene un oggetto xhr e tutti i parametri della mia chiamata ajax, tra le altre cose).

Ho provato a fare questo:

$.ajax({ 
    /* ... */ 
    success: function() { this.some_callback(); }, 
}); 

ma ho l'errore:
Uncaught TypeError: Object #<an Object> has no method 'handle_response'

io non sono sicuro di come fare correttamente questo. Sono nuovo di JavaScript e il concetto di prototipo-che-a-volta-tipo-di-comportarsi-come-classi-ma-di solito-non mi sta davvero confondendo.

Quindi qual è il modo giusto per farlo? Sto cercando di forzare JavaScript in un paradigma a cui non appartiene?

risposta

12

Am I trying to force JavaScript into a paradigm which it doesn't belong?

Quando parli di Classi si.

So what is the right way to do this?

Prima di tutto, si dovrebbe imparare che tipo di valori la parola this può contenere.

  1. funzione di chiamata semplice

    myFunc(); - this farà riferimento all'oggetto globale (aka window) [1] chiamata

  2. funzione come una proprietà di un oggetto (aka metodo)

    obj.method(); - this volontà fare riferimento a obj

  3. chiamata di funzione lungo arguzia il nuovo operatore

    new MyFunc(); - this si riferiscono alla new instance sta creando

Ora vediamo come si applica al vostro caso:

MyClass.prototype.open = function() { 
    $.ajax({ // <-- an object literal starts here 
     //... 
     success: this.some_callback, // <- this will refer to that object 
    });  // <- object ends here 
} 

Se si desidera chiamare il metodo some_callback dell'istanza corrente e salvare il riferimento a tale istanza (su una variabile semplice).

MyClass.prototype.open = function() { 
    var self = this; // <- save reference to the current instance of MyClass 
    $.ajax({ 
     //... 
     success: function() { 
      self.some_callback(); // <- use the saved reference 
     }       // to access instance.some_callback 
    });        
} 

[1] si ricorda che nella nuova versione (ES 5 Str.) Caso 1 causerà this essere il valore undefined

[2] C'è ancora un altro caso in cui si utilizzare call o apply per richiamare una funzione con un dato this

+0

va bene, ho provato questo, ma il mio risultato è lo stesso: la chiamata a 'opere some_callback', ma' this' all'interno di 'some_callback' si riferisce al un oggetto di richiesta jax che hai evidenziato nel tuo primo esempio di codice. Come posso chiamare 'some_callback' in modo che, all'interno del callback,' this' si riferisca all'oggetto 'MyClass' che imposta il callback? –

+0

Ho avuto un bug minore. Aggiornata la risposta. – galambalazs

+0

l'esempio aggiornato funziona come un incantesimo. Pensavo di aver già provato e non ha funzionato ... Suppongo di aver fatto un errore quando ho provato quel metodo prima. –

Problemi correlati