Pregunta

esta cosa casi funciona:

function myClass(url) {

this.source = url;
this.rq = null;
this.someOtherProperty = "hello";

// open connection to the ajax server
this.start = function() {
    if (window.XMLHttpRequest) {
        this.rq = new XMLHttpRequest();
        if (this.rq.overrideMimeType)
        this.rq.overrideMimeType("text/xml"); 
    } else
        this.rq = new ActiveXObject("Microsoft.XMLHTTP");

    try {
        this.rq.onreadystatechange = connectionEvent;
        this.rq.open("GET", this.source, true);
        this.rq.send(null);
        this.state = 1;
    } catch (err) {
        // some error handler here
    }

}

function connectionEvent() {
    alert("i'm here");
    alert("this doesnt work: " + this.someOtherProperty);
}

} // myClass

por lo que no es nada más que tener el objeto XMLHttpRequest como miembro de mi clase, en lugar de a nivel mundial definido, y que lo alega, de la manera tradicional. Sin embargo, dentro de mi función de devolución de llamada ConnectionEvent, el significado de "este" se pierde, a pesar de que la función en sí está en el ámbito interior myClass. i también se aseguró de que el objeto que crear una instancia de myClass se mantiene con vida el tiempo suficiente (declarado global en el guión).

en todos los ejemplos de la utilización de clases de javascript que he visto, "esto" era todavía disponibles dentro de las funciones internas. para mí, no lo es, incluso si me tomo mi función fuera y convertirlo en un myClass.prototype.connectionEvent. ¿Qué estoy haciendo mal? gracias.

¿Fue útil?

Solución

La razón por la que no funciona es que en Javascript, this se define en su totalidad por la forma de una función es llamada , no en donde está definido. Esto es diferente a otros idiomas.

Para tener this media lo que espera, usted tendría que asegurarse de que explícitamente por "unión" que:

this.start = function() {
    var self = this; // Set up something that survives into the closure

    /* ...lots of stuff omitted... */

    this.rq.onreadystatechange = function() {
        // Call `connectionEvent`, setting `self` as `this` within the call
        connnectionEvent.call(self);
    };

Hay más información acerca de la gestión this en esta entrada del blog , pero básicamente: Cuando se invoca una función sin ningún esfuerzo especial de que se establezca this, this dentro de la función será siempre el objeto global (window, en los navegadores). Hay dos maneras de configurar this al hacer una llamada:

  1. Uso Function#call (o Function#apply) como lo hice anteriormente, que pasa en la referencia de objeto que se utiliza como this como el primer parámetro. Que llama a la función y conjuntos this a lo que se ha pasado. La diferencia entre #call y #apply es la forma de suministro adicional argumentos para pasar a la función. Con #call que les suministran como argumentos adicionales a la llamada (por ejemplo #call func.call(thisArg, arg0, arg1, arg2)), mientras que con #apply que les suministran como una matriz en el segundo argumento (func.apply(thisArg, [arg0, arg1, arg2])).
  2. Uso de notación: Si usted tiene un objeto que tiene una propiedad con una función asignada a ella (como su propiedad start), que calificó mediante el uso de la instancia del objeto, un punto y el nombre de la propiedad (this.start() o foo.start(), etc. .) llamará a la función y el conjunto de this a la instancia del objeto dentro de la llamada. Por lo que la notación hace dos completamente distintas cosas: busca la propiedad y se encuentra una función como su valor, y llama a la función tal que this se establece en el objeto durante la llamada. Literalmente es como:. var f = obj.func; f.call(obj)

Un poco fuera de tema, pero: Salvo una muy buena razón para, yo no reinventar esta rueda. Hay un montón de bibliotecas que hay para llamadas con sólo XHR. jQuery , Prototype , Cierre , y casi todo el resto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top