Skip to content
返回

addEventListener 的第二个参数还可以是一个对象

今天在开发 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 中有了箭头函数,这个方法大概以后也不会有更多人知道了吧。


分享这篇文章:

上一篇
更友好的操作 localStorage 与 sessionStorage
下一篇
手机浏览器在后台运行时会阻塞 JavaScript 进程