全面解析 JavaScript 类继承:方式、优缺点与应用场景

在 JavaScript 中,"继承"指的是让一个对象或类能够复用另一个对象或类的属性和方法。

由于 JavaScript 的面向对象机制是基于 原型(prototype) 而非传统类,因此继承方式丰富多样,从 ES5 时代的手动原型链,到 ES6 之后的 class 语法糖,都有不同的实现手段。

本文将系统介绍 8 种主要继承方式 ,分析它们的优缺点适用场景,并提供代码示例。


1. class 继承(ES6 extends

js 复制代码
class Parent {
  greet() { console.log("Hello from Parent"); }
}
class Child extends Parent {
  greet() { super.greet(); console.log("...and from Child"); }
}
new Child().greet();

优点

  • 语法简洁,接近 Java / C# 等语言。
  • 内置 super 调用父类构造和方法。
  • 支持继承内置对象(Array, Error 等)。
  • 性能接近最佳(底层是寄生组合继承)。

缺点

  • 只是语法糖,本质仍是原型链。
  • 高级场景(动态改继承结构)需理解原型机制。

适用场景

  • 现代前端、Node.js 项目的默认选择。

2. class + 表达式继承(动态继承)

js 复制代码
function mixin(base) {
  return class extends base {
    extra() { console.log("extra"); }
  }
}
class Parent {}
class Child extends mixin(Parent) {}
new Child().extra();

优点

  • 运行时动态决定父类。
  • 易于组合多个基类。

缺点

  • 可读性差,调试困难。

适用场景

  • 插件系统、UI 组件动态扩展。

3. 原型链继承

js 复制代码
function Parent() { this.colors = ["red", "blue"]; }
Parent.prototype.say = function() { console.log("parent"); };

function Child() {}
Child.prototype = new Parent();
Child.prototype.constructor = Child;

优点

  • 实现简单。
  • 子类可直接访问父类原型方法。

缺点

  • 属性被所有实例共享(引用类型容易出错)。
  • 无法向父类构造传参。

适用场景

  • 学习原型链原理,已不推荐在生产使用。

4. 借用构造函数继承

js 复制代码
function Parent(name) { this.name = name; }
function Child(name) { Parent.call(this, name); }

优点

  • 每个实例的属性独立。
  • 可传参。

缺点

  • 无法继承父类原型方法,方法需重复定义。

适用场景

  • 仅继承属性,不需要父类方法的简单对象。

5. 组合继承

js 复制代码
function Parent(name) { this.name = name; }
Parent.prototype.say = function() { console.log(this.name); };

function Child(name) {
  Parent.call(this, name); // 继承属性
}
Child.prototype = new Parent(); // 继承方法
Child.prototype.constructor = Child;

优点

  • 继承父类属性与方法。
  • 子类实例独立。

缺点

  • 父类构造函数被调用两次。

适用场景

  • ES5 最常用方式,简单可靠。

6. 寄生组合继承

js 复制代码
function inherit(Child, Parent) {
  Child.prototype = Object.create(Parent.prototype);
  Child.prototype.constructor = Child;
}
function Parent(name) { this.name = name; }
Parent.prototype.say = function() { console.log(this.name); };

function Child(name) {
  Parent.call(this, name);
}
inherit(Child, Parent);

优点

  • 父类构造只调用一次,性能好。
  • 完整继承属性和方法。

缺点

  • 写法比组合继承稍复杂。

适用场景

  • ES5 推荐的最佳继承方案。

7. 原型式继承

js 复制代码
let parent = { greet() { console.log("hello"); } };
let child = Object.create(parent);
child.greet();

优点

  • 极简,无需构造函数。
  • 灵活,适合快速克隆对象。

缺点

  • 属性共享,引用类型有风险。
  • 无法传参初始化。

适用场景

  • 创建配置模板、数据对象。

8. 寄生式继承

js 复制代码
function createChild(o) {
  let clone = Object.create(o);
  clone.say = function() { console.log("hi"); };
  return clone;
}
let parent = { greet() { console.log("hello"); } };
let child = createChild(parent);
child.say();

优点

  • 在原型式继承基础上增强对象。
  • 灵活度高。

缺点

  • 方法无法复用,浪费内存。

适用场景

  • 一次性对象增强。

9. Mixin 混入

js 复制代码
const sayMixin = { say() { console.log("hi"); } };
class Person {}
Object.assign(Person.prototype, sayMixin);

优点

  • 模拟多继承。
  • 灵活扩展功能。

缺点

  • 命名冲突风险。
  • 方法来源分散,不易维护。

适用场景

  • 事件系统、功能扩展。

继承方式对比表

方式 优点 缺点 推荐度 场景
class 继承 语法简洁,支持 super 语法糖,本质是原型链 ⭐⭐⭐⭐⭐ 现代项目
class + 表达式 动态父类 可读性差 ⭐⭐⭐ 插件系统
原型链继承 简单直观 属性共享,不能传参 学习原理
借用构造函数 属性独立,可传参 不继承方法 ⭐⭐ 仅需属性
组合继承 属性独立+继承方法 调用两次父构造 ⭐⭐⭐⭐ ES5 常用
寄生组合继承 性能最佳 写法稍复杂 ⭐⭐⭐⭐⭐ ES5 推荐
原型式继承 极简 属性共享 ⭐⭐ 对象克隆
寄生式继承 灵活增强 无法复用方法 ⭐⭐ 一次性增强
Mixin 多继承效果 命名冲突风险 ⭐⭐⭐ 功能扩展

结语

  • 如果是 现代项目 :优先使用 class extends
  • 如果是 ES5 项目 :用 寄生组合继承
  • 如果只是克隆/增强对象:用 Object.createMixin
  • 学习原型链原理时,可以用最简单的原型链继承练习。

理解继承方式,不仅是写代码的技巧,更是掌握 JavaScript 对象模型的关键。

相关推荐
夏幻灵12 分钟前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_25 分钟前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js
未来龙皇小蓝29 分钟前
RBAC前端架构-01:项目初始化
前端·架构
程序员agions37 分钟前
2026年,微前端终于“死“了
前端·状态模式
万岳科技系统开发37 分钟前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
程序员猫哥_1 小时前
HTML 生成网页工具推荐:从手写代码到 AI 自动生成网页的进化路径
前端·人工智能·html
龙飞051 小时前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
我爱加班、、1 小时前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao1 小时前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
杨超越luckly1 小时前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强