removeEventListener 移除绑定的 this.xxx 事件无效问题

2019/5/30 Javascript

当 addEventListener 监听绑定的事件为 this.getName 时,getName 方法里面的 this 指向会不正确,比如:

class Test {
  constructor(name){
    this.name = name
  }

  getName(){
    console.log(this.name)
  }

  doSomething(){
    window.addEventListener('click' this.getName)
  }
}
// 此时getName里面的this会指向window
1
2
3
4
5
6
7
8
9
10
11
12
13
14

如果想要让 this 正确指向 Test,则需要这样写:

class Test {
  constructor(name){
    this.name = name
  }

  getName(){
    console.log(this.name)
  }

  doSomething(){
    window.addEventListener('click' this.getName.bind(this))
  }
}
// 此时getName里面的this会指向Test
1
2
3
4
5
6
7
8
9
10
11
12
13
14

但是这样就有个问题,导致无法移除绑定事件:

window.removeEventListener('click' this.getName)
window.removeEventListener('click' this.getName.bind(this))
// 两种写法都是不能正确移除绑定事件的
1
2
3

因为 bind()方法会创建一个新函数,当这个新函数被调用时,它的 this 值是传递给 bind()的第一个参数, 它的参数是 bind()的其他参数和其原本的参数.

所以正确的做法是:

class Test {
  constructor(name){
    this.name = name
    this.getName = this.getName.bind(this)
  }

  getName(){
    console.log(this.name)
  }

  doSomething(){
    window.addEventListener('click' this.getName)
    // this正确指向Test,打印出 name
    window.removeEventListener('click' this.getName)
    // 正确移除事件
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

参考:

最后更新: 2022/8/5 09:49:24