JS将类实例方法赋值给DOM元素属性时无法访问属性报错如何解决?
问题根源
你遇到的报错本质是JavaScript中this的运行时绑定规则导致的:
- 类中声明的普通方法的
this不是预先绑定到实例的,会根据调用方式动态确定 - 把方法单独赋值给其他变量(比如DOM元素的属性)后,调用时
this指向的是调用这个方法的宿主对象(这里就是DOM元素本身),而非类实例 - 调用
call时如果不传第一个参数,严格模式下this会被设为undefined,自然读取不到实例上的属性
解决方案
场景1:将方法赋值给DOM元素属性直接调用
方案1:使用bind硬绑定this指向
将方法赋值时,提前把this固定到类实例上:
el = document.querySelector('#updateNameForm'); el.A = new A(); // bind的第一个参数就是方法执行时固定的this指向 el.ajaxA = el.A.getA.bind(el.A);
之后直接调用el.ajaxA()即可正常执行。
方案2:用箭头函数包装
利用箭头函数不绑定自身this、继承外层上下文的特性,保证方法调用时this指向实例:
el.ajaxA = () => el.A.getA();
方案3:类内部预先绑定方法this
直接在类定义时将方法声明为箭头函数,让方法的this永久绑定到实例本身:
class A { constructor() { this.a = 'a'; } // 箭头函数方法,this固定为当前实例 getA = () => { return this.a; } }
之后直接赋值el.ajaxA = el.A.getA即可正常调用。
场景2:方法绑定到DOM事件
和上述逻辑一致,只要保证回调执行时this指向类实例即可:
无需后续移除事件的场景
直接用箭头函数或者bind:
// 方式1:bind绑定 el.addEventListener('submit', el.A.getA.bind(el.A)); // 方式2:箭头函数包装,还可以自定义处理事件对象 el.addEventListener('submit', (e) => { e.preventDefault(); // 可自行处理事件默认行为 el.A.getA(); });
需要后续移除事件的场景
不要使用匿名函数,提前把绑定好的回调存为变量,保证移除时的引用一致:
// 先存储绑定后的回调引用 const boundAjaxHandler = el.A.getA.bind(el.A); // 绑定事件 el.addEventListener('submit', boundAjaxHandler); // 后续移除事件 el.removeEventListener('submit', boundAjaxHandler);
补充说明
你之前执行el.A.getA.call()报错的原因是没有给call传指定this的第一个参数,改为el.A.getA.call(el.A)即可正常执行。
内容的提问来源于stack exchange,提问作者GatesPlan
相关产品推荐
相关产品推荐

