javascript - nodejs - Care "this" este acesta?


Deci, aceasta este o întrebare stânjenitoare de pus, dar învăț NodeJS și am o întrebare. În Java, când apelez o metodă dintr-un obiect, instanța this rămâne aceeași (așa cum se arată în acest exemplu).

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

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

Acesta returnează adevărat (în teorie, acesta este codul din capul meu). Totuși, în NodeJS, când încerc să fac ceva similar, eșuează.

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.
}

Întrebarea mea este de ce este astfel, și dacă acest lucru este făcut incorect din partea mea, cum pot face corect referire la alte variabile din instanța MyObject din metoda onError?

Răspuns #1

În JavaScript, „metodele” sunt doar funcții care fac parte dintr-un obiect.

Dacă faci

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

Acest în onError va fi obiectul obj (deoarece este obiectul din care este invocat)

În schimb, în cazul tău, transmiți this.onError către EventEmitter, acesta va apela funcția respectivă cu EventEmitter (OtherObject) ca this.

Pentru a evita această problemă, folosește o funcție anonimă.

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

În acest fel, legați acest lucru înapoi la obiectul pe care îl așteptați

Răspunsul #2

Există o modalitate mai simplă - poți folosi funcția bind.

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

Demonstrație