JavaScript继承库类时重写箭头函数形式的类方法不生效问题
子类重写父类类字段方法不生效问题解析
核心原因
- 类实例字段(
submitHandler = () => {}语法)的初始化顺序遵循:父类实例字段初始化 → 父类constructor执行 → 子类实例字段初始化。父类A的constructor执行绑定事件时,子类B的submitHandler还未完成赋值,此时取到的是父类定义的默认方法引用。 - 事件监听器绑定的是函数引用快照,绑定完成后后续修改
this.submitHandler的指向,不会影响已经注册的监听器,因此触发事件时始终调用最初绑定的父类方法。
解决方案
场景1:无法修改第三方库的A类代码
可以通过捕获阶段优先监听的方式拦截原有逻辑,也可根据需求选择是否调用父类原有方法:
class B extends A { constructor(options) { super(options); // 绑定在捕获阶段,会早于父类默认的冒泡阶段监听执行 this._searchForm.addEventListener('submit', this.submitHandler.bind(this), true); } submitHandler = (e) => { // 阻止事件继续传播,跳过父类绑定的冒泡阶段监听 e.stopPropagation(); e.preventDefault(); console.log('New'); // 如有需要可保留父类逻辑:super.submitHandler(e) } }
场景2:可修改A类的实现代码
建议将方法改为原型方法,事件绑定时用箭头函数包装动态读取当前实例的方法,即可原生支持继承重写:
class A { constructor (options) { this._searchForm = options.searchForm // 触发时才动态读取当前实例的submitHandler,避免绑定固定引用 this._searchForm.addEventListener('submit', (e) => this.submitHandler(e)) } // 改为原型方法,而非类实例字段 submitHandler(e) { console.log('Default') } }
优化后子类直接重写submitHandler即可正常生效:
class B extends A { submitHandler(e) { console.log('New') } }
内容的提问来源于stack exchange,提问作者alpha787
相关产品推荐
相关产品推荐

