如何在作为addEventListener回调的类方法中访问私有属性
问题根因
你遇到的报错本质是JavaScript函数this指向丢失导致的:当你直接把load.next作为回调传入addEventListener时,函数被调用时的this会被绑定到触发点击事件的DOM元素上,而非Load类的实例对象。而类的私有属性只能被对应类的实例上下文访问,指向DOM元素的this自然没有权限读取私有属性,就抛出了对应的错误。你用getter访问无效也是同理,因为此时this根本不是类实例,getter自然拿不到正确的值。
可行解决方案
- 方案1:绑定回调的this指向
传入回调时用bind方法显式将this绑定到load实例即可,修改事件绑定代码:
document.querySelector('div').addEventListener('click', load.next.bind(load));
- 方案2:将类方法定义为箭头函数
箭头函数的this会继承定义时的上层作用域上下文,也就是类实例本身,修改next方法的定义:
class Load { #start; #end; constructor(){ this.#start = 0; this.#end = 5; } get start(){return this.#start} get end(){return this.#end} // 改为箭头函数定义 next = (evt) => { const event = evt.target; event.innerText = `start: ${this.#start}. end: ${this.#end}`; } }
后续直接传load.next作为回调即可,不需要额外绑定。
- 方案3:用匿名函数包裹回调调用
在事件绑定时用箭头函数包裹一层,保证next是通过load实例调用的,此时this会自动指向实例:
document.querySelector('div').addEventListener('click', (evt) => load.next(evt));
- 方案4:构造函数内提前绑定方法
在类的构造函数中提前把next方法的this绑定到当前实例,后续使用不需要额外处理:
class Load { #start; #end; constructor(){ this.#start = 0; this.#end = 5; // 构造函数内提前绑定this this.next = this.next.bind(this); } get start(){return this.#start} get end(){return this.#end} next(evt){ const event = evt.target; event.innerText = `start: ${this.#start}. end: ${this.#end}`; } }
内容的提问来源于stack exchange,提问作者Schnitzler
相关产品推荐
相关产品推荐

