今天在开发 https://github.com/lmk123/t-rex-runner 的过程中,深扒了一下恐龙游戏的源码,居然看到下面这段代码:
Runner.prototype = {
// ...
startListening: function() {
document.addEventListener( 'keydown', this );
// ...
}
};
看到这里我惊呆了。一直以来,我都知道 addEventListener 的第二个参数必须是一个函数,但是,上面这段代码直接将 this 作为参数,并且代码没有报错、游戏运行正常!
这时,我注意到 startListening 方法上面还有一个 handleEvent 方法,但它的颜色是灰色的(Webstorm 会把未使用过的方法、函数或变量变为灰色):
Runner.prototype = {
// ...
handleEvent: function(e) {
// ...
},
startListening: function() {
document.addEventListener( 'keydown', this );
// ...
}
};
我注释掉这个方法之后再运行游戏,就发现按空格或点鼠标没反应了——吓得我赶紧去谷歌了一下,然后在 MDN 上找到了这段内容:(出处)
var Something = function(element) {
this.name = 'Something Good';
this.handleEvent = function(event) {
console.log(this.name); // 'Something Good', as this is the Something object
switch(event.type) {
case 'click':
// some code here...
break;
case 'dblclick':
// some code here...
break;
}
};
// Note that the listeners in this case are this, not this.handleEvent
element.addEventListener('click', this, false);
element.addEventListener('dblclick', this, false);
// You can properly remove the listeners
element.removeEventListener('click', this, false);
element.removeEventListener('dblclick', this, false);
}
这是何等的黑科技,写了三年的 JavaScript,我还是头一回知道这回事!!你要是不相信,可以看看这个在线示例。
简单来说,这个方法的目的是将事件处理函数里的 this 指向另外一个对象。但在 ES 2015 中有了箭头函数,这个方法大概以后也不会有更多人知道了吧。