JavaScript无原生“选择性继承”开关,但可通过原型链继承(复用方法、隔离实例属性)、构造函数继承(传参初始化、独享属性)、寄生组合继承(最优:一次调用+属性独立+方法复用)及手动删/覆写原型方法等方式实现按需继承。

JavaScript 继承机制本身不提供“选择性继承”的语法开关,但可以通过不同继承方式的组合与手动控制,实现对属性和方法的按需继承——即让某些属性私有独立、某些方法共享复用、某些则完全不继承。
只继承方法,不继承实例属性(原型链继承)
把父类方法定义在 prototype 上,子类原型直接指向父类实例或用 Object.create(Parent.prototype),就能复用方法,但避开父类构造函数中初始化的实例属性(如 this.colors = [])。
- 父类构造函数里的引用类型属性(数组、对象)不会被子类实例继承,避免共享污染
- 所有子类实例共用同一套原型方法,节省内存
- 缺点:无法向父类构造函数传参;子类实例没有父类的实例属性(如
name、id)
只继承实例属性,不继承原型方法(构造函数继承)
在子类构造函数中用 Parent.call(this, ...args),仅执行父类构造逻辑,把 this 上的属性(包括基本类型和新创建的引用类型)复制到当前实例。
- 每个子类实例拥有独立的属性副本,互不影响
- 支持向父类传参,初始化更灵活
- 缺点:父类
prototype上的方法(如sayHi())不会出现在子类实例上,需额外挂载或重写
按需混合:属性隔离 + 方法复用(寄生组合继承)
这是目前最接近“选择性继承”的手写方案:用 call 继承实例属性,用 Object.create(Parent.prototype) 设置子类原型,跳过 new Parent() 的冗余调用。
- 父类构造函数只执行一次,避免组合继承中两次初始化的开销
- 子类实例有自己独立的
this.name、this.items等,不共享 - 子类原型链正确连接到
Parent.prototype,可调用Parent.prototype.walk()等方法 - 若某方法不想继承,不把它放在
Parent.prototype上即可(比如只保留在父类构造函数内)
彻底排除:手动过滤或重写原型
即使已建立继承关系,也可在子类原型设置后,显式删除不需要的方法:
delete Child.prototype.unwantedMethod- 或覆盖为
Child.prototype.problematicMethod = function() { throw new Error('Not supported'); } - 若父类方法依赖被屏蔽的实例属性,需同步检查逻辑兼容性


















