JS 实现继承的几种方式

ops/2024/10/18 7:45:58/

现在有parent、child两个函数,child函数的实例想要访问parent函数的属性和方法(child想要继承parent)。

1、原型链继承

缺点:有引用的值共享的问题

即当parent某个属性是引用数据类型的时候,child实例如果修改了这个属性的内容则其他的child实例中这个属性也会一起改变(正常来说应该是互不干扰的,原始数据类型属性就是互不干扰的)

function parent(){this.data = '我是parent'
}function child(){}child.prototype = new parent()var fun = new child()console.log(fun.data)

2、构造函数集成

通过在child函数中独立执行parent( 此时parent的this指向window ),然后通过call方法改变parent的指向指向child实例( parent.call(this) ),这样new出来的child实例就能访问到parent中的属性和方法了。这种方法就称为构造函数继承。

缺点:使用这种方法child实例没有办法拿到parent函数原型上的属性和方法。

function parent(){this.data = '我是parent'
}parent.prototype.say = function(){console.log("我是parent原型")
}function child(){parent.call(this)
}var fun = new child()console.log(fun.data)        // 输出“我是parent”
fun.say()                    // 此处报错

3、组合继承(构造函数+原型链)

这个方法是结合了上述的两个方法:

  • 用构造函数继承中的child函数独立执行parent来解决原型链继承的引用值共享问题
  • 用原型链继承中child函数的原型指向parent的实例来解决构造函数中child实例无法访问parent原型上属性和方法的问题。

 缺点:new了两次parent,会产生了属性与方法重叠的问题。

function parent(){this.data = '我是parent'
}parent.prototype.say = function(){console.log("我是parent原型")
}function child(){parent.call(this)
}child.prototype = new parent()var fun = new child()console.log(fun.data)
fun.say()

 4、寄生组合继承(经典继承)

(第三种方法)组合继承:无论什么情况下,都会调用两次父类的构造函数。寄生组合式继承就解决了上述问题,被认为是最理想的继承方式。

function parent(){this.data = '我是parent'
}parent.prototype.say = function(){console.log("我是parent原型")
}function child(){parent.call(this)
}child.prototype = Object.create(parent.prototype)var fun= new child()console.log(fun.data)
fun.say()

5、原型式继承

原型式继承是一种基于已有对象创建新对象的继承方式,适用于简单对象的继承。在 JavaScript 中可以使用 Object.create 方法来实现原型式继承。

// 原型对象
var parent = {name: 'parent',age: 30,say: function () {return '我是' + this.name}
}// 基于原型对象创建新对象
var child= Object.create(parent)child.name = 'Alice'   // 修改属性值
child.age = 25         // 修改属性值console.log(child.say()) // 输出 "我是 Alice"

6、es6的extends类继承 

 child类通过extends继承了parent类的属性和方法。

class Parent {constructor(name) {this.name = name}// 原型方法// 即 Parent.prototype.getName = function() { }// 下面可以简写为 getName() {...}getName = function () {console.log('Parent:', this.name)}
}
class Child extends Parent {constructor(name, age) {// 子类中存在构造函数,则需要在使用“this”之前首先调用 super()。super(name)this.age = age}
}
const asuna = new Child('Asuna', 20)
asuna.getName() // 成功访问到父类的方法


http://www.ppmy.cn/ops/37287.html

相关文章

欧鹏RHCE 第四次作业

unit4.web服务的部署及高级优化方案 1. 搭建web服务器要求如下: 1.web服务器的主机ip:172.25.254.100 2.web服务器的默认访问目录为/var/www/html 默认发布内容为default‘s page 3.站点news.timinglee.org默认发布目录为/var/www/virtual/timinglee.org…

【spark(零)】spark技术概览

文章目录 一. Spark入门二. Spark RDD与 Spark core三. Spark SQL四. Spark Streaming五. Spark内核原理 一. Spark入门 Spark基础知识 Spark部署模式、 Spark运行流程 【概述】spark(一):spark特点、知识范畴、spark架构、任务提交流程、支持哪些运行…

力扣热题100刷题笔记[python]

letcode100 题录地址: https://leetcode.cn/studyplan/top-100-liked/ 注:另外有记忆精简版 [LeetCode热题100_记忆版.md](file:///D:/yingl/文件/notes_-yl/技术精品文章/编程基本功/算法资料汇总/LeetCode热题100_记忆版.md) 哈希 两数之和 思路: 0、用 hash_table =…

整体安全保障服务方案包括哪些方面?

整体安全保障服务方案是一套综合性的措施,旨在保护企业的网络、数据和资源免受各种威胁。主要包含检测、加固、应急保障、安全运营、攻防演练等多项核心能力与服务。 ​安全狗通过专业团队、工具以及专业运营流程,提出了新一代整体安全保障思路&#xff…

Linux——mysql运维篇

回顾基本语句: 数据定义语言 ( DDL ) 。这类语言用于定义和修改数据库的结构,包括创建、删除和修改数据库、表、视图和索引等对象。主要的语句关键字包括 CREATE 、 DROP 、 ALTER 、 RENAME 、 TRUNCATE 等。 create database 数据库 &…

提供 DISC性格测试报告的全新 API接口,带给你惊喜的发现!

简介 DISC个性测验由24组描述个性特质的形容词构成,每组包含四个形容词,这些形容词是根据支配性(D)、影响性(I)、服从性(C)、 稳定性(S)和四个测量维度以及一…

简要介绍MATLAB的背景和重要性,以及它在数据分析与可视化领域的广泛应用

**标题**:MATLAB在数据分析与可视化中的应用 **引言**(约200字) 简要介绍MATLAB的背景和重要性,以及它在数据分析与可视化领域的广泛应用。强调本文旨在探讨MATLAB在这两个领域的具体应用案例、技术特点和发展趋势。 **一、MAT…

你对氟橡胶油封的基本知识了解多少?

在机械和工程领域,氟橡胶油封在确保平稳运行和防止泄漏方面发挥着至关重要的作用。了解这些密封件的基本知识对于任何参与制造、维护或维修过程的人来说都是至关重要的。 1.组成与结构: 氟橡胶油封主要由氟、碳和氢原子组成,因此得名氟弹性…