(chiết xuất một số giải thích rằng được giấu trong bình luận trong câu trả lời khác)
Vấn đề nằm ở dòng sau:
this.dom.addEventListener("click", self.onclick, false);
Ở đây, bạn vượt qua một đối tượng chức năng được sử dụng như gọi lại . Khi sự kiện kích hoạt, chức năng được gọi nhưng bây giờ nó không có liên kết với bất kỳ đối tượng (điều này).
Vấn đề có thể được giải quyết bằng cách gói các chức năng (với tham chiếu đối tượng của nó) trong một kết thúc như sau:
this.dom.addEventListener(
"click",
function(event) {self.onclick(event)},
false);
Kể từ khi tự biến được gán này khi đóng cửa đã được tạo ra, chức năng đóng cửa sẽ nhớ giá trị của biến tự khi nó được gọi sau đó.
Một cách khác để giải quyết việc này là để thực hiện một chức năng hữu ích (và tránh sử dụng các biến cho ràng buộc này):
function bind(scope, fn) {
return function() {
fn.apply(scope, arguments);
};
}
Mã được cập nhật sau đó sẽ như thế nào:
this.dom.addEventListener("click", bind(this, this.onclick), false);
Function.prototype.bind
là một phần của ECMAScript 5 và cung cấp chức năng tương tự. Vì vậy, bạn có thể làm:
this.dom.addEventListener("click", this.onclick.bind(this), false);
Đối với trình duyệt mà không hỗ trợ ES5 nào, MDN provides the following shim:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function() {},
fBound = function() {
return fToBind.apply(this instanceof fNOP
? this
: oThis || window,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
Chức năng tiện ích createCallback rất tiện dụng! cảm ơn. –
closure() có lẽ là tên tốt hơn. – hishadow
Hoặc liên kết() hoặc bindMethod(). – outis