回撥和 this
通常在使用回撥時,你希望訪問特定的上下文。
function SomeClass(msg, elem) {
this.msg = msg;
elem.addEventListener('click', function() {
console.log(this.msg); // <= will fail because "this" is undefined
});
}
var s = new SomeClass("hello", someElement);
解決方案
-
使用
bind
bind
有效地生成一個新函式,將this
設定為傳遞給bind
的任何內容,然後呼叫原始函式。function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', function() { console.log(this.msg); }.bind(this)); // <=- bind the function to `this` }
-
使用箭頭函式
箭頭函式自動繫結當前的
this
上下文。function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click',() => { // <=- arrow function binds `this` console.log(this.msg); }); }
通常,你希望呼叫成員函式,理想情況下將傳遞給事件的任何引數傳遞給函式。
解決方案:
-
使用 bind
function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', this.handleClick.bind(this)); } SomeClass.prototype.handleClick = function(event) { console.log(event.type, this.msg); };
-
使用箭頭函式和其餘運算子
function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', (...a) => this.handleClick(...a)); } SomeClass.prototype.handleClick = function(event) { console.log(event.type, this.msg); };
-
特別是對於 DOM 事件監聽器,你可以實現
EventListener
介面function SomeClass(msg, elem) { this.msg = msg; elem.addEventListener('click', this); } SomeClass.prototype.handleEvent = function(event) { var fn = this[event.type]; if (fn) { fn.apply(this, arguments); } }; SomeClass.prototype.click = function(event) { console.log(this.msg); };