JS 的继承方式与使用场景

news/2025/2/7 8:36:57/文章来源:https://www.cnblogs.com/is-DW/p/18701993

在 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️⃣原型式/寄生式继承主要用于对象克隆而非类继承场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/879926.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ZW3D二次开发_入门_Action与Ribbon菜单定制--转自 知乎 捣蛋龙

ZW3D二次开发_入门_Action与Ribbon菜单定制捣蛋龙 ​关注他5 人赞同了该文章​ 目录收起ZW3D二开入门目录 - 知乎 (zhihu.com)最新测试环境:2025 SP前言定制Ribbon菜单1.新建工作区2.定义"行为"3.定义自定义Ribbon文件4.编写策略文件5.编写引导程序6.多环境差异化策…

day4

简单图论与构造 A 考虑把权值为 2 的点看作给权值为 1 的点加一, 所以整个问题被拆成了两个部分:构造树和给节点加一 事实上,在第一部分时我们将树构造的尽量平衡是有好处,这个结论在第二个步骤中会得到证明 构造: Process DFS(father,ch,u,size):if size==0 then returnso…

Omnissa Horizon Windows OS Optimization Tool 2412 - Windows 系统映像优化工具

Omnissa Horizon Windows OS Optimization Tool 2412 - Windows 系统映像优化工具Omnissa Horizon Windows OS Optimization Tool 2412 - Windows 系统映像优化工具 Optimizing Images Using Omnissa Horizon Windows OS Optimization Tool 请访问原文链接:https://sysin.org/…

BOM最全基础信息:标准件、通用件、替换件、必选件

在生产制造领域,物料清单(BOM)是产品设计、生产计划和供应链管理的核心基础。本文系统梳理了BOM中各类零部件的分类方法,供大家参考。在生产制造的复杂领域中,我们会与各式各样的产品组成部分打交道。清晰、准确地对它们进行分类,并实施有效的管理,对于提升生产效率、保…

人工智能辅助芯片设计

芯片设计:一个近乎无限的问题空间 设计复杂性呈指数级增长 设计复杂性的含义 一连串棘手的问题 贯穿整个流程优化 HDL生成研究 使用GCN加速设计评估 人工智能辅助验证 参考文献链接https://www.hc2024.hotchips.org/assets/program/tutorials/3-HC24.synopsys.SteliosDiaman…

应用随机过程 | 期末 cheat sheet

出分后发布笔记……这篇博客汇总了「应用随机过程」2018 - 2022 的期末试题,并根据题型分类总结。 本站相关博客:应用随机过程 | 期末知识点总结特别鸣谢:知乎 | 九一居士 |《应用随机过程》课程笔记系列目录1 马尔可夫链计算题2 常返的马尔可夫链3 连续时间参数的马尔可夫链…

推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》4本书,非常感谢

4本书推荐《AI芯片开发核心技术详解》、《智能汽车传感器:原理设计应用》、《TVM编译器原理与实践》、《LLVM编译器原理与实践》由清华大学出版社资深编辑赵佳霓老师策划编辑的新书《AI芯片开发核心技术详解》已经出版,京东、淘宝天猫、当当等网上,相应陆陆续续可以购买。该…

OpenVX基本原理与历史

OpenVX基本原理 2.1 引言 2.1.1 摘要 OpenVX 是一个低级编程框架域,用于支持软件开发人员,可高效访问计算机视觉硬件加速功能和性能的可移植性。OpenVX 旨在支持现代硬件架构,例如,移动和嵌入式 SoC 以及桌面系统。其中许多系统是并行和异构的:多个处理器类型包括多核 CPU…

L4D2自制角色Mod - HUI篇

如何以相对简易的思路自制求生之路2求生者头像Mod本文是笔者尝试制作 求生之路2 角色 Mod 的过程中编写的笔记,笔者的背景是有基础的计算机知识和图像处理软件的使用经验,相信大多数读者朋友都有同样的水平。本文面向希望能快速简单地自定义游戏内角色图像/模型,但对更深层次…

使用Netty与前端请求进行交互实现实时通讯

引言因为不满足与一般的SpringBoot CRUD开发(太无聊了)所以去学一下网络编程,第一站就是通过B站老罗的EasyChat项目了解到了Netty这个网络框架,在学习这个项目之前也是去学习了一下Netty框架的使用以及相关的原理知识所以是有一定了解的,但是只是一味的学习不去实践总感觉是空中…

如何使用 Filebeat 8 连接 Easysearch

在日志场景,还是有很多小伙伴在使用 Filebeat 采集日志的。今天我来实战下使用 Filebeat 8 连接 Easysearch 。本次使用 Easysearch-1.9.0 版本和 Filebeat-8.17.0 版本做演示,也适用 Filebeat-oss-8.17.0 版本。 Easysearch 不开启兼容参数的情况 Easysearch 默认情况下未开…