Frage

das Ding fast funktioniert:

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

Es ist also nichts anderes als ein Mitglied meiner Klasse das XMLHttpRequest-Objekt mit, statt global definiert ist, und es in der traditionellen Art und Weise aufgerufen wird. aber in meiner Connectioncallback-Funktion, die Bedeutung von „dieser“ verloren geht, auch wenn die Funktion selbst innerhalb myClass scoped ist. Ich stellte sicher, dass das Objekt, dass ich von myClass instanziiert wird lange genug am Leben (deklarierte globale im Skript) gehalten.

In allen Beispielen von JavaScript-Klassen, die ich sah, „das“ war in den inneren Funktionen nach wie vor zur Verfügung. für mich ist es nicht, auch wenn ich meine Funktion außerhalb nehmen und es sich um eine myClass.prototype.connectionEvent machen. Was mache ich falsch? danke.

War es hilfreich?

Lösung

Der Grund, es nicht funktioniert, dass in Javascript, this definiert wird vollständig durch, wie eine Funktion ist genannt , nicht dort, wo es definiert wird. Dies ist anders als einige andere Sprachen.

haben this Mittelwert, was Sie erwarten, dann würden Sie, dass explizit durch „verbindlich“ sicherzustellen, müssen sie:

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);
    };

Es gibt mehr Informationen über this Management in diesem Blog-Eintrag , aber im Grunde: Wenn eine Funktion ohne besondere Anstrengungen unternommen, um Satz this, this innerhalb der Funktion wird immer das globale Objekt (window, über Browser) aufgerufen wird. Es gibt zwei Möglichkeiten, um Satz this, wenn Sie einen Anruf tätigen:

  1. Mit Function#call (oder Function#apply) wie ich oben tat, vorbei in den Objektverweis als this als ersten Parameter zu verwenden. Das ruft die Funktion und setzt this, was auch immer Sie übergeben. Der Unterschied zwischen #call und #apply ist, wie Sie weitere Argumente liefern in die Funktion zu übergeben. Mit #call versorgen Sie sie als weitere Argumente an die #call Anruf (z.B. func.call(thisArg, arg0, arg1, arg2)), während bei #apply man sie als Array in dem zweiten Argument Versorgung (func.apply(thisArg, [arg0, arg1, arg2])).
  2. gepunktete Schreibweise verwenden: Wenn Sie ein Objekt haben, das eine Eigenschaft mit einer Funktion zugeordnet ist (wie Ihre start Eigenschaft), nennt es durch die Objektinstanz verwenden, um einen Punkt, und den Namen der Eigenschaft (this.start() oder foo.start(), etc .) wird die Funktion und die Set this auf die Objektinstanz innerhalb des Anrufs nennen. So ist die Punkt-Notation macht zwei völlig verschieden Dinge: Sieht die Eigenschaft und eine Funktion als Wert findet, und ruft die Funktion, so dass this auf das Objekt während des Gesprächs festgelegt ist. Wörtlich ist es wie:. var f = obj.func; f.call(obj)

Ein wenig Off-Topic, aber: einen wirklich guten Grund Barring, würde ich dieses Rad nicht neu erfinden. Es gibt viele Bibliotheken da draußen einfach XHR Anrufe. jQuery , Prototype Closure , und fast der ganze Rest.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top