You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript父类存在同名实例属性时是否会忽略子类同名方法?

表现是否符合预期

该表现完全符合ECMAScript的标准规范,不属于异常。

背后的运行原理

核心原因是类公共实例字段和类原型方法的定义位置、初始化时机存在本质差异:

  • Base类中get = () => {}属于公共实例字段,会在类实例化阶段(调用super()时)直接作为属性挂载到生成的实例对象自身,不是定义在Base.prototype上的原型方法
  • Child类中get() {}属于原型方法,只会挂载到Child.prototype上,不会出现在实例对象自身

JS访问对象属性的优先级是:先查找对象自身的属性,找不到才会沿原型链向上查找。调用child.get()时,优先匹配到了实例自身由Base类初始化生成的get箭头函数,自然不会触发原型链上Child的get方法。

更合理的实现方案

你当前的实现会在实例上新增公开的parentGet属性,污染实例命名空间,推荐用私有属性存储父类方法的方案,不会对外暴露内部存储的父类方法:

class Base {
    get = () => {
        console.log('i am the Base function');
    }
}

class Child extends Base {
    // 声明私有属性存储父类get方法,外部无法访问修改
    #parentGet;
    constructor() {
        super();
        // super执行完成后,父类的get已经挂载到实例,先存储再覆盖
        this.#parentGet = this.get;
    }
    // 子类的实例字段赋值在super之后执行,直接覆盖父类的get属性
    get = () => {
        console.log('i am the Child function');
        this.#parentGet();
    }
}

const child = new Child();
child.get(); // 先输出'i am the Child function',再输出'i am the Base function'

如果你的运行环境不支持ES私有属性,可以用Object.defineProperty结合闭包的方案实现,不会在实例上新增额外可访问属性:

class Child extends Base {
    constructor() {
        super();
        const parentGet = this.get;
        Object.defineProperty(this, 'get', {
            enumerable: true,
            configurable: true,
            value: () => {
                console.log('i am the Child function');
                parentGet();
            }
        })
    }
}

内容的提问来源于stack exchange,提问作者tomsidorov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 23:42:00