JavaScript类中方法互调报错:Uncaught TypeError问题排查
问题解答
首先明确:完全可以在类的一个方法中调用另一个类方法,你的代码问题出在事件绑定后this的指向丢失了。
错误原因
当你把formContact.formSubmit作为回调传给addEventListener时,这个方法会在事件触发时被当作普通函数调用,此时this不再指向Form的实例formContact,而是指向触发事件的DOM元素(也就是formContact.form这个表单元素)。而DOM元素上并没有checkPhone方法,所以会抛出类型错误。
解决方法
有几种简单的修复方式:
方法1:用箭头函数包裹回调
箭头函数会继承外层作用域的this,这里就是formContact实例:
formContact.form.addEventListener("submit", (el) => formContact.formSubmit(el));
方法2:在构造函数中绑定this
在constructor里提前把formSubmit的this绑定到类实例:
constructor (classForm, name, email, phone, text) { // 保留原有的DOM查询代码 this.form = document.querySelector(`.contactForm`); this.name = document.querySelector(`.contactForm [name=${name}]`); this.email = document.querySelector(`.contactForm [name=${email}]`); this.phone = document.querySelector(`.contactForm [name=${phone}]`); this.text = document.querySelector(`.contactForm [name=${text}]`); this.submit = document.querySelector(`.contactForm [name=submit]`); // 新增绑定代码 this.formSubmit = this.formSubmit.bind(this); }
之后正常绑定事件即可:
formContact.form.addEventListener("submit", formContact.formSubmit);
方法3:用类字段定义箭头函数(ES6+)
直接把formSubmit定义为箭头函数,它的this会始终指向类实例:
class Form { constructor (classForm, name, email, phone, text) { // 原有的DOM查询代码不变 this.form = document.querySelector(`.contactForm`); this.name = document.querySelector(`.contactForm [name=${name}]`); this.email = document.querySelector(`.contactForm [name=${email}]`); this.phone = document.querySelector(`.contactForm [name=${phone}]`); this.text = document.querySelector(`.contactForm [name=${text}]`); this.submit = document.querySelector(`.contactForm [name=submit]`); } checkPhone () { return this.phone.value.length >= 12; } // 改成箭头函数形式 formSubmit = (el) => { console.log(this.checkPhone()) el.preventDefault(); console.log('not') } }
这种方式不需要额外绑定,直接用原有的事件绑定代码就行。
验证修复
无论用哪种方法,修复后formSubmit里的this都会指向Form实例,调用this.checkPhone()就能正常访问到类方法了。
内容的提问来源于stack exchange,提问作者Serhii Prudkyi
相关产品推荐
相关产品推荐

