当前位置: 首页 > 知识库问答 >
问题:

ES6类:在方法[duplicate]上应用“add eventlistener”访问“this”

邵伟
2023-03-14

在这个es6脚本中,click事件不起作用,因为sayHello方法是用this.elm(

)作为 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);
  }
}

匿名用户

这是一个常见的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);

共有2个答案

仲学真
2023-03-14
相关问题
郑承恩
2023-03-14

这是一个常见的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);
 类似资料:
  • 我想在另一个类中使用那个擦除方法,但由于它看起来不是静态的,所以我不能这样做 那么我如何访问那个方法呢?

  • 问题内容: 假设我正在构建一个井字游戏(因为它与结构非常相似),我希望结果在弹出窗口中显示,并带有一个新的游戏按钮,并且希望此弹出窗口允许我访问设置(另一个按钮)并对其进行更改,使其始终位于弹出窗口中,然后离开并最终将其关闭并开始新游戏。 我希望我可以保持秩序,因此有一个单独的弹出窗口类,可以在其中构建自定义弹出窗口。 显而易见,我将newgame方法和reset方法作为我的游戏网格类的方法。另一

  • 问题内容: 考虑到这一节课;我将如何迭代其中包含的方法? 我尝试过的以下操作均未成功: 问题答案: 您可以在原型上使用Object.getOwnPropertyNames:

  • 我是kubernetes的新手,我尝试使用Kubernete运行小型应用程序。我创建了docker镜像并使用minikube运行它。所以应用程序非常简单,它只打印hello world。 我的dockerfile文件: deployment.yaml 我运行命令: 创建deployment.yaml 输出是: 服务/myhelloworldservice已创建 创建的部署.apps/我的问候世界

  • 当我在Spring开机时调用肥皂服务时,我会出错。我使用cxf wsdl2java实现服务方法。我可以将wsdl成功导入到sap-ui。但是我不能发送帖子请求到服务。 有没有什么意见,我该如何解决这个问题? 这是完整的stacktace。 2019-05-22 16:22:21.339警告1388---[nio-8081-exec-4]o.a.cxf。阶段相位接收链:应用{http://quota

  • 问题内容: 只是一个简单的问题:是否可以从c / c ++调用Java函数? 问题答案: 是的,你可以,但是它有点令人费解,并且以反射/非类型安全的方式工作(示例使用的C ++ API比C版本更干净)。在这种情况下,它将从C代码中创建Java VM的实例。如果首先从Java调用你的本机调用,则无需构造VM实例 编译(在Ubuntu上): 注意:为了实现正确的错误处理,应检查每种方法的返回代码(为方