JS 的继承方式与使用场景对比分析

 更新时间:2025年02月07日 08:48:29   作者:啊哈哈哈哈哈h  
本文介绍了JavaScript中六种主要的继承实现方式及其适用场景,并推荐在现代项目中优先使用ES6的class继承,每种继承方式都有其特点和适用范围,选择合适的继承方式对于编写清晰、高效的JavaScript代码至关重要,感兴趣的朋友一起看看吧

在 JavaScript 中,继承的实现方式主要有以下几种,每种方式适用于不同的场景:

一、原型链继承

实现方式

function Parent() { this.name = 'Parent'; }
Parent.prototype.say = function() { return this.name; };
function Child() {}
Child.prototype = new Parent(); // 原型继承关键
const child = new Child();
child.say(); // 输出 "Parent"

特点

  • 子类实例通过原型链访问父类属性和方法
  • 问题:父类的引用类型属性会被所有子类实例共享

场景

  • 简单继承结构,无引用类型共享问题需求的场景
  • 老项目快速实现继承(现代开发不推荐优先使用)

二、构造函数继承

实现方式

function Parent(name) { this.name = name; }
function Child(name) {
  Parent.call(this, name); // 构造函数继承关键
}
const child = new Child('Child');
child.name; // 输出 "Child"

特点

  • 将父类属性复制到子类实例
  • 优点:解决引用属性共享问题
  • 缺陷:无法继承父类原型上的方法

场景

  • 需要 实例属性独立性的场景(如每个对象需要独立状态)
  • 不支持子类复用父类原型方法(若无需复用则合适)

三、组合继承(经典继承)

实现方式

function Parent(name) {
  this.name = name;
}
Parent.prototype.say = function() { return this.name };
function Child(name) {
  Parent.call(this, name); // 第1次调用父类构造函数
}
Child.prototype = new Parent(); // 第2次调用父类构造函数(问题根源)
Child.prototype.constructor = Child;
const child = new Child('Child');
child.say(); // 输出 "Child"

特点

  • 结合原型链继承(方法继承)和构造函数继承(属性继承)
  • 缺陷:父类构造函数被调用两次,子类原型中存在冗余属性

场景

  • 传统项目的常规继承需求(ES6 出现前的常见方案)
  • 需要同时满足方法复用和实例属性独立的场景

四、原型式继承

实现方式

const parent = { name: 'Parent', friends: ['Alice'] };
const child = Object.create(parent); // 核心API
child.name = 'Child';
child.friends.push('Bob'); // friends被所有基于parent创建的对象共享

特点

  • 类似于对象浅拷贝
  • 问题:引用类型属性共享(与原型链相同)

场景

  • 简单对象继承需求(无构造函数存在的场景)
  • 原型链的极简替代方案(如旧环境无 Object.create 时的 polyfill

五、寄生式继承

实现方式

function createChild(parent) {
  const obj = Object.create(parent);
  obj.sayHi = () => 'Hi'; // 添加额外方法
  return obj;
}
const child = createChild({ name: 'Parent' });

特点

  • 工厂模式增强对象
  • 缺陷:方法无法复用,类似构造函数问题

场景

  • 需要给对象快速扩展额外方法的场景
  • 不适合大型继承结构(复用性差)

六、寄生组合式继承(最优解)

实现方式

function inheritPrototype(Child, Parent) {
  const prototype = Object.create(Parent.prototype); // 创建父类原型的副本
  prototype.constructor = Child; // 修复构造函数指向
  Child.prototype = prototype; // 赋值给子类原型
}
function Parent(name) { this.name = name; }
Parent.prototype.say = function() { return this.name; };
function Child(name) {
  Parent.call(this, name); // 属性继承
}
inheritPrototype(Child, Parent); // 方法继承

特点

  • 只调用一次父类构造函数,避免组合继承的冗余问题
  • 保留完整的原型链结构

场景

  • 现代项目推荐的标准继承方式
  • 适用于所有复杂继承需求(效率最高)

七、ES6 class 继承

实现方式

class Parent {
  constructor(name) { this.name = name }
  say() { return this.name }
}
class Child extends Parent { // extends 关键字
  constructor(name) {
    super(name); // super调用父类构造函数
  }
}
const child = new Child('Child');
child.say(); // 输出 "Child"

特点

  • 语法糖,本质基于原型和寄生组合式继承
  • 支持 staticsuper 等特性

场景

  • 现代项目首选方式
  • 需要清晰类结构、继承关系明确的场景

总结与场景对比

继承方式适用场景现代选择优先级
原型链继承快速实现简单原型链(已过时)⭐️
构造函数继承需要独立实例属性的场景⭐️⭐️
组合继承传统项目兼容性解决方案⭐️⭐️
寄生组合式继承需要高效且标准的继承方案⭐️⭐️⭐️⭐️
ES6 class 继承现代项目开发(Babel转译后兼容性好)⭐️⭐️⭐️⭐️⭐️

实际开发建议

  • 优先使用 ES6 class 继承(清晰、易维护,Babel 转译后底层使用寄生组合式继承)
  • 旧项目维护时根据现有模式选择组合或寄生组合继承
    4️⃣原型式/寄生式继承主要用于对象克隆而非类继承场景

到此这篇关于JS 的继承方式与使用场景的文章就介绍到这了,更多相关JS 继承方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS async 函数的含义和用法实例总结

    JS async 函数的含义和用法实例总结

    这篇文章主要介绍了JS async 函数的含义和用法,结合实例形式总结分析了JS async 函数的基本功能、含义、使用方法及操作注意事项,需要的朋友可以参考下
    2020-04-04
  • 详解小程序如何改变onLoad的执行时机

    详解小程序如何改变onLoad的执行时机

    这篇文章主要介绍了详解小程序如何改变onLoad的执行时机,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • js前端导出Excel的方法

    js前端导出Excel的方法

    这篇文章主要为大家详细介绍了js前端导出Excel的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 详谈构造函数加括号与不加括号的区别

    详谈构造函数加括号与不加括号的区别

    下面小编就为大家带来一篇详谈构造函数加括号与不加括号的区别。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Bootstrap4 gulp 配置详解

    Bootstrap4 gulp 配置详解

    这篇文章主要介绍了Bootstrap4 gulp 配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • 详解js中let与var声明变量的区别

    详解js中let与var声明变量的区别

    这篇文章主要介绍了let与var声明变量区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • js Event对象的5种坐标

    js Event对象的5种坐标

    使用鼠标事件经常碰到这样的需求,比如获取鼠标相对于事件源的位置,鼠标相对于事件源对象父元素的位置
    2011-09-09
  • js实现简单页面全屏

    js实现简单页面全屏

    这篇文章主要为大家详细介绍了js实现简单页面全屏的功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 一篇文章让你彻底搞懂js中的位置计算

    一篇文章让你彻底搞懂js中的位置计算

    js中有各种与位置相关的属性,每次看到的时候都各种懵逼,索性一次总结一下,这篇文章主要给大家介绍了关于js中位置计算的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2021-09-09
  • JS 字符串连接[性能比较]

    JS 字符串连接[性能比较]

    js字符串连接实现代码。
    2009-05-05

最新评论