如何正确将DOM事件处理程序绑定到Web应用类的方法?
问题:类中DOM事件绑定的优雅实现方式
我习惯把Web应用的某部分功能封装在类里,但绑定DOM事件处理程序时总遇到this指向的问题。
目前能用的方案是这样的:
class MyModule { constructor() { this.somedata = somevalue; let me = this; $("#somediv").on("click", function() { // 这里的'this'指向DOM中的div元素 me.somediv_onClick(this); }); } somediv_onClick(divElement) { // 这里的'this'指向MyModule实例 // 可以正常访问this.somedata let div = $(divElement); div.html(this.somedata); } }
但用let me = this来保存实例引用的写法感觉有点繁琐。
我试过更简洁的写法,但达不到预期效果:
class MyModule { constructor() { $("#somediv").on("click", this.somediv_onClick); } somediv_onClick(event) { // 这里的'this'指向被点击的DOM元素 // 没法访问MyModule实例的属性 let div = $(this); div.html( ... ? ...); } }
有没有更简洁优雅的实现方式?
方案1:使用箭头函数
箭头函数不会绑定自身的this,会继承外层作用域的this(也就是类的实例),无需额外保存引用:
class MyModule { constructor() { this.somedata = somevalue; $("#somediv").on("click", (event) => { // 此处this直接指向MyModule实例 let div = $(event.currentTarget); div.html(this.somedata); // 也可以直接调用类方法,方法内的this同样指向实例 this.somediv_onClick(event.currentTarget); }); } somediv_onClick(divElement) { let div = $(divElement); div.html(this.somedata); } }
方案2:构造函数内绑定方法的this
在构造函数中用bind()强制把类方法的this绑定到实例,之后直接传递方法引用即可:
class MyModule { constructor() { this.somedata = somevalue; // 将方法的this绑定到当前实例 this.somediv_onClick = this.somediv_onClick.bind(this); $("#somediv").on("click", this.somediv_onClick); } somediv_onClick(event) { // 此处this指向MyModule实例 // 通过event.currentTarget获取触发事件的DOM元素 let div = $(event.currentTarget); div.html(this.somedata); } }
方案3:类字段定义箭头函数(ES6+)
如果运行环境支持类字段语法,可以直接把方法定义为箭头函数,这样它的this会永久绑定到类实例:
class MyModule { constructor() { this.somedata = somevalue; $("#somediv").on("click", this.somediv_onClick); } // 类字段形式的箭头函数,this始终指向实例 somediv_onClick = (event) => { let div = $(event.currentTarget); div.html(this.somedata); } }
内容的提问来源于stack exchange,提问作者Bart Friederichs
相关产品推荐
相关产品推荐

