2015-07-02 23 views
6

Also das ist eine unangenehme Frage zu stellen, aber ich lerne NodeJS und ich habe eine Frage. Wenn ich in Java eine Methode von einem Objekt aus anrufe, bleibt die this Instanz dieselbe (wie in diesem Beispiel).nodejs - Welches "das" ist das?

private Test inst; 
public Test() { 
    inst = this; 
    this.myFunction(); 
} 

private void myFunction() { 
    System.out.println(inst == this); 
} 

Dies ist wahr (in der Theorie ist das Code von der Spitze meines Kopfes). Wenn ich jedoch in NodeJS versuche, etwas Ähnliches zu tun, schlägt es fehl.

var MyObject = function() { 
    this.other = new OtherObject(); 
    this.other.on("error", this.onError); 
    console.log(this); //This returns the MyObject object 
} 

MyObject.prototype.onError = function (e) { 
    console.log(this); //This returns the OtherObject object, where I thought it would return the MyObject object. 
} 

Meine Frage ist, warum dies so ist, und wenn dies nicht richtig auf meinem Teil getan wird, wie kann ich richtig andere Variablen in der MyObject-Instanz aus der onError Methode verweisen?

+0

AFAIK, 'this' in Javascript, ist sehr schwierig. Wenn es in Funktion aufgerufen wird, zeigt es auf den Aufrufer und nicht auf das Objekt, für das die Funktion definiert ist. – walther

+1

@ walther- * das * in Javascript ist überhaupt nicht schwierig. Es ist durch den Aufruf festgelegt, oder die Verwendung von * bind *, das ist es. Obwohl es sich von anderen Sprachen unterscheidet, ist es nicht wirklich schwer zu verstehen. – RobG

+0

@RobG, das ist genau der schwierige Teil - andere Sprachen machen es anders und es verwirrt die Hölle von einigen Entwicklern. Wenn es wirklich so klar wäre, würde eine solche Frage niemals aufkommen (und dies ist nicht das erste oder das letzte Mal). – walther

Antwort

6

In JavaScript sind "Methoden" nur Funktionen, die Teil eines Objekts sind.

Wenn Sie das tun

var obj = new MyObject(); 
obj.onError(); 

Das dies in onError wird das obj-Objekt sein (weil es das Objekt aus aufgerufen wird)

Statt in Ihnen Fall, dass Sie vorbei this.onError an die EventEmitter wird diese Funktion mit dem EventEmitter (OtherObject) aufrufen.

Um dieses Problem zu vermeiden, verwenden Sie eine anonyme Funktion.

var MyObject = function() { 
    var self = this; 
    this.other = new OtherObject(); 
    this.other.on("error", function (e) { self.onError(e); }); 
} 

Auf diese Weise können Sie diese zurück an das Objekt binden erwarten Sie

+1

Vielen Dank, dass Sie das so gut erklärt haben, und für das großartige Anwendungsbeispiel! – duper51

+1

Für eine noch sauberere Lösung verwenden Sie die Bind-Methode https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind – B3rn475

+0

@RobG es war eine Semplification. Übrigens behoben – B3rn475

0

Es ist einfacher Art und Weise - Sie binden Funktion nutzen zu können.

var EventEmitter = require('events').EventEmitter; 

var MyObject = function() { 
    this.other = new EventEmitter(); 
    this.other.on("error", this.onError.bind(this)); 
    console.log(1, this instanceof MyObject); // 1, true 
}; 

MyObject.prototype.onError = function (e) { 
    console.log(2, this instanceof MyObject); // 2, true 
}; 

MyObject.prototype.callError = function (e) { 
    console.log(3, this instanceof MyObject); // 3, true 
    this.other.emit('error', e); 
}; 

var mo = new MyObject(); 

mo.callError(new Error(1)); 

Demo

Verwandte Themen