2010-10-25 17 views
5

Estoy teniendo un momento realmente difícil envolviendo mi cabeza en torno a los prototipos en JavaScript.No se pueden usar los métodos de "clase" para las devoluciones de llamada en JavaScript

Anteriormente había problemas para llamar a algo como esto:

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

y me dijeron que podía solucionarlo mediante el uso de:

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

y esto funciona. Ahora estoy teniendo un problema diferente, y pensé que podría resolverlo de la misma manera, simplemente ingresando en una función anónima. Mi nuevo problema es el siguiente:

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

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

estoy encontrando que dentro del cuerpo de la palabra clave MyClass.prototype.some_callbackthis no se refiere a la instancia de MyClass el que el método se denomina en adelante, sino más bien lo que parece ser el jQuery solicitud ajax (es un objeto que contiene un objeto xhr y todos los parámetros de mi llamada ajax, entre otras cosas).

He intentado hacer esto:

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

pero me sale el error:
Uncaught TypeError: Object #<an Object> has no method 'handle_response'

No estoy seguro de cómo hacerlo correctamente esto. Soy nuevo en JavaScript y el concepto de prototipos-que-a veces-tipo-de-comportarse-como-clases-pero-por lo general-no me confunde realmente.

Entonces, ¿cuál es la forma correcta de hacerlo? ¿Estoy tratando de forzar JavaScript en un paradigma al que no pertenece?

Respuesta

12

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

Cuando hablamos de Clases sí.

So what is the right way to do this?

En primer lugar, usted debe aprender qué tipo de valores puede contener la palabra clave this.

  1. llamada de función simple

    myFunc(); - this se referirá al objeto global (también conocido como window) [1] llamada

  2. función como una propiedad de un objeto (también conocido como método)

    obj.method(); - this will consulte obj

  3. llamada de función a lo largo de ingenio el nuevo operador

    new MyFunc(); - this se referirá a la new instance creándose

Ahora vamos a ver cómo se aplica a su caso:

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

If Si desea llamar al método some_callback de la instancia actual, debe guardar la referencia a esa instancia (a una variable simple).

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] Téngase en cuenta que en la nueva versión (ES 5 Str.) Caso 1 hará que this a ser el valor undefined

[2] Hay otro caso en el que se utilizar call o apply para invocar una función con un determinado this

+0

bien, he intentado esto, pero mi resultado es el mismo: la llamada a 'obras some_callback', pero' 'this' interior de some_callback' se refiere a la una objeto de solicitud jax que ha resaltado en su primer ejemplo de código. ¿Cómo puedo llamar a 'some_callback' de forma que, dentro de la devolución de llamada,' this' se refiera al objeto 'MyClass' que establece la devolución de llamada? –

+0

Tuve un error menor. Actualizado la respuesta. – galambalazs

+0

su ejemplo actualizado funciona como un encanto. Pensé que ya lo había intentado y no funcionó ... Supongo que cometí un error cuando probé ese método antes. –

Cuestiones relacionadas