【问题标题】:ES6 Class: access to 'this' with 'addEventListener' applied on method [duplicate]ES6类:在方法上应用'addEventListener'访问'this'
【发布时间】:2015-08-07 10:09:40
【问题描述】:

在这个 es6 脚本中,click 事件不起作用,因为 sayHello 方法是用 this.elm (<div>) 作为 this 调用的。

如何在不丢失范围的情况下将事件关联到方法?

class player{
  constructor (name) {
    this.name = name;
    this.elm = document.createElement('div');
    this.elm.addEventListener('click', this.sayHello);
  }
  sayHello() {
    console.log(this.name + ' say: "hello!"'); // 'undefined say 'hello!"';
  }
  kill() {
    console.log(`RIP ${this.name} :'(`); 
    this.elm.addClass('dead');
    this.elm.removeEventListener('click', this.sayHello);
  }
}

【问题讨论】:

    标签: javascript dom ecmascript-6 dom-events


    【解决方案1】:

    这是一个通用的JS问题,但它的核心是

    this.elm.addEventListener('click', this.sayHello);
    

    没有什么不同
    var fn = this.sayHello;
    this.elm.addEventListener('click', fn);
    

    您正在传递一个函数作为事件处理程序,但未确保在调用 fn 时将 this 设置为您想要的值。在 ES5 中最简单的方法是

    this.elm.addEventListener('click', this.sayHello.bind(this));
    

    或者在 ES6 中,使用箭头函数:

    this.elm.addEventListener('click', evt => this.sayHello(evt));
    

    但是请注意,这两种解决方案都会破坏您在kill 中的(已经稍微损坏的)逻辑,因为

    this.elm.removeEventListener('click', /* what? */);
    

    您不再对附加的函数有任何引用,因此您无法删除事件处理程序。

    我建议两个选项:

    // Create a new function that is bound, and give it a new name
    // so that the 'this.sayHello()' call still works.
    this.boundSayHello = evt => this.sayHello(evt);
    this.elm.addEventListener('click', this.boundSayHello);
    this.elm.removeEventListener('click', this.boundSayHello);
    

    // Bind the function with the same name and use `.bind` instead of the
    // arrow function option.
    this.sayHello = this.sayHello.bind(this);
    this.elm.addEventListener('click', this.sayHello);
    this.elm.removeEventListener('click', this.sayHello);
    

    【讨论】:

    • 谢谢,这是我用的,但是每个对象都需要有一个对象指向每个绑定函数需要作为回调codepen.io/yukulele/pen/yNVVxV/?editors=001
    • 太棒了!我更喜欢第一个解决方案。首先我尝试了 .bind(this) 但在尝试获取 this 范围内的其他变量时失败了,因为我在 ES6 类中。
    • 啊,所以 canvas.addEventListener('mousedown', pad_mouseDown, false); 在 ES6 类样式中将是 this.canvas.addEventListener('mousedown', evt=> this.pad_mouseDown(evt), false);
    猜你喜欢
    • 1970-01-01
    • 2016-12-12
    • 2018-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2015-06-04
    相关资源
    最近更新 更多