javascript - nodejs - "this" này là của cái nào?
Vì vậy đây là một câu hỏi hơi khó hỏi, nhưng tôi đang học NodeJS và tôi có một câu hỏi. Trong Java, khi tôi gọi một phương thức từ một đối tượng, thể hiện this vẫn giữ nguyên (như trong ví dụ này).
private Test inst;
public Test() {
inst = this;
this.myFunction();
}
private void myFunction() {
System.out.println(inst == this);
}
Điều này trả về true (về lý thuyết, đó là mã tôi nghĩ ngay lập tức). Tuy nhiên, trong NodeJS khi tôi cố gắng làm điều gì đó tương tự thì nó thất bại.
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.
}
Câu hỏi của tôi là tại sao lại như vậy, và nếu điều này đang được thực hiện không đúng bởi tôi, làm thế nào tôi có thể tham chiếu đúng các biến khác trong đối tượng MyObject từ phương thức onError?
Câu trả lời #1
Trong JavaScript, "phương thức" chỉ là các hàm là một phần của đối tượng.
Nếu bạn làm
var obj = new MyObject();
obj.onError();
`this` trong `onError` sẽ là đối tượng `obj` (bởi vì nó là đối tượng mà từ đó nó được gọi)
Thay vào đó, trong trường hợp của bạn, bạn đang truyền this.onError cho EventEmitter, nó sẽ gọi hàm đó với EventEmitter (OtherObject) như this.
Để tránh vấn đề đó, hãy sử dụng một hàm ẩn danh.
var MyObject = function () {
var self = this;
this.other = new OtherObject();
this.other.on("error", function (e) { self.onError(e); });
}
Bằng cách này, bạn đang gắn kết điều này trở lại với đối tượng mà bạn mong đợi
Câu trả lời số 2
Có một cách đơn giản hơn - bạn có thể sử dụng hàm 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));
Bản trình diễn
