返回顶部
首页 > 资讯 > 前端开发 > JavaScript >浅谈JavaScript的几种继承实现方式
  • 412
分享到

浅谈JavaScript的几种继承实现方式

JavaScrip继承 2023-05-17 08:05:14 412人浏览 薄情痞子
摘要

目录当前需求: 实现 Student 继承自 Person构造函数Person构造函数Student希望满足的条件功能利用原形链实现方法的继承方式1: 子类原型指向父类原型方式2 子

当前需求: 实现 Student 继承自 Person

如果手动实现继承效果, Person和Student分别写自己的属性和方法, 两个构造函数之间没有任何关联

  • 代码编写繁琐
  • 可维护性低

构造函数Person

function Person(name, age, height, address) {
	this.age = age
	this.height = height
	this.address = address
}

Person.prototype.running = function() {
	console.log("running~")
}

Person.prototype.eating = function() {
	console.log("eating~")
}

构造函数Student

function Student(name, age, height, address, sno, score) {
	this.age = age
	this.height = height
	this.address = address
	this.sno = sno
	this.score = score
}

Student.prototype.running = function() {
	console.log("running~")
}
Student.prototype.eating = function() {
	console.log("eating~")
}
Student.prototype.studying = function() {
	console.log("studying~")
}

内存图

Pasted image 20230419141544.png

希望满足的条件功能

Student构造函数满足以下条件

  • 能够重写继承的方法, 但不修改Person原型上的方法.
  • 能够增加方法, 但不会影响Person原型上的方法.

Student构建出的实例对象满足以下条件

  • 有name, age, height, address属性, 并且扩充sno和score. 作为自己独立的属性.
  • 继承running, eating方法, 和Person实例对象的方法有相同的引用.

利用原形链实现方法的继承

方式1: 子类原型指向父类原型

function Student(age, height, address, sno, score) {
	this.age = age
	this.height = height
	this.address = address
	this.sno = sno
	this.score = score
}

+ Stuednt.prototype = Person.prototype

内存图

Pasted image 20230419142001.png

缺点

父类和子类共享通一个原型对象, 修改了任意一个, 另外一个也被修改

方式2 子类原型指向父类实例对象

function Student(sno, score) {
	this.sno = sno
	this.score = score
}
+ var p = new Person()
+ Student.prototype = p

内存图

Pasted image 20230419142506.png

缺点

  • 属性放在了原型上, 无法通过打印查看.
  • 创建的多个实例对象, 继承的属性不互相独立, 一个实例对象修改属性影响其他的实例对象
  • 要new一个实例, 怪怪怪怪怪怪

借用构造函数继承

方式3 组合继承

function Person(name, age, height, address) {
	this.name = name
	this.age = age
	this.height = height
	this.address = address
}
Person.prototype.running = ...

function Student(age, height, address, sno, score) {
+   Person.call(this, age, height, address)
	this.sno = sno
	this.score = score
}

Student.prototype = new Person()

内存图

Pasted image 20230419165358.png

优点

解决之前的硬性问题, 实例对象属性独立, 属性放在对象内而不是原型上.

缺点

  • 调用两次父类的构造方法, 性能浪费
    • Student.prototype = new Person()第一次
    • Person.call(this)第二次
  • 调用两次构造方法, 导致子类创建的实例对象上, 保留了两份父类的属性
    • 一份在实例对象的__proto__上, new时产生的
    • 一份在实例对象上, 通过借用构造方法call得到

寄生式继承

思路

属性的继承已经解决, 通过Person.call(this) 解决.

方法的继承未解决, 需要找到 Student.prototype = new Person() 的替代方案

思路1

var obj = {}
obj.__proto__ = Person.prototype
Student.prototype = obj

// __proto__为浏览器增加的属性, 解决浏览器兼容性问题可以改为
var obj = {}
Object.setPrototypeOf(obj, Person.prototype)
Student.prototype = obj

思路2

兼容所有浏览器 解决老版本浏览器不支持setPrototypeOf

function F() {}
F.prototype = Person.prototype
Student.prototype = new F()

思路3

Object.create() 传入一个对象作为参数, 并返回一个对象, 返回的对象的原型为传入对象

var obj = Object.create(Person.prototype)
Student.prototype = obj 

最终 方式4: 寄生组合式继承

// 工具函数
// 创建对象的过程
function createObject(proto) {
	function F() {}
	F.prototype = proto 
	return new F()
}

// 将Subtype和Supertype联系在一起
// 寄生式函数
function inherit(Subtype, Supertype) {
	Subtype.prototype = createObject(Supertype.prototype)
	Object.defineProperty(Subtype.prototype, "constructor", {
		enumerable: false,
		configurable: true,
		writable: true,
		value: Subtype
	})
}

function Student(age, height, sno, score) {
	Person.call(this, age, height)
	this.sno = sno
	this.score = score
}

+ inherit(Student, Person)

// 使用方法
Student.prototype.studying = function() {
	console.log("studying")
}

💡 使用Person.call实现属性的继承

💡 使用inherit实现方法的继承

  • createObject 使Student.prototype指向Person的prototype, 但中间多一个构造函数F(), 解决方式1 的问题
  • Object.defineProperty 实现 Student.prototypeconstructor 属性指回Student构造函数.内存图

image.png

附: 扩充createObject

最初的设计思想, 是为了实现对象的继承, 所以有了以下的代码

createObject只能够做到构造一个有原型的空对象, 现在想要让构造的对象也有属性

createInfo(proto, age, height) {
	const newObj = this.createObject(proto)
	newObj.age = age
	newObj.height = height
	return newObj
}

到此这篇关于浅谈javascript的几种继承实现方式的文章就介绍到这了,更多相关JavaScrip 继承内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 浅谈JavaScript的几种继承实现方式

本文链接: https://lsjlt.com/news/210910.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 浅谈JavaScript的几种继承实现方式
    目录当前需求: 实现 Student 继承自 Person构造函数Person构造函数Student希望满足的条件功能利用原形链实现方法的继承方式1: 子类原型指向父类原型方式2 子...
    99+
    2023-05-17
    JavaScrip 继承
  • 分享JavaScript 中的几种继承方式
    目录一、原型链1.1 原型链的问题二、盗用构造函数2.1 基本思想2.2 可向父类构造函数传参2.3 盗用构造函数的问题三、组合继承(伪经典继承)3.1 基本思想3.2 组合继承的问...
    99+
    2024-04-02
  • JavaScript中常见的几种继承方式
    目录原型继承内存图分析盗用构造函数继承分析组合继承原型链继承寄生式继承寄生组合式继承原型继承 function Parent(name) { this.name = name }...
    99+
    2024-04-02
  • c++继承的实现方式有哪几种
    在C++中,有三种继承的实现方式:公有继承、私有继承和保护继承。 公有继承: 公有继承是最常用的继承方式。使用关键字"publi...
    99+
    2023-10-26
    c++
  • JavaScript实现继承的7种方式总结
    目录什么是继承实现继承的6种方式1. 原型链继承2. 构造函数继承3. 组合继承(伪经典继承)4. 原型式继承5. 寄生式继承6.寄生组合式继承7.class 类继承什么是继承 用官...
    99+
    2023-05-14
    JavaScript实现继承方式 JavaScript继承方式 JavaScript继承
  • 浅谈前端JS沙箱实现的几种方式
    目录前言 iframe实现沙箱 diff方式实现沙箱 基于代理(Proxy)实现单实例沙箱 基于代理(Proxy)实现多实例沙箱 结束语 参考前言 在微前端领域当中,沙箱是很重要的...
    99+
    2024-04-02
  • JavaScript实现继承的6种常用方式总结
    目录1.原型链继承2.借用构造函数继承3.组合继承(经典继承)4.原型式继承方法一:借用构造函数方法二:Object.create()5.寄生式继承6.寄生组合式继承7.ES6、Cl...
    99+
    2024-04-02
  • c++继承的方式有哪些几种
    C++中有以下几种继承的方式: 公有继承(public inheritance):使用public关键字来指定基类和派生类之间的...
    99+
    2024-02-29
    c++
  • 在c++中继承方式有几种
    c++中的主要继承方式包括:公有继承:子类继承父类的所有公开和受保护成员,可以访问它们的公开和受保护成员。受保护继承:子类继承父类的所有受保护和公开成员,可以访问它们的受保护和公开成员。...
    99+
    2024-05-12
    c++
  • javascript继承实现的方式有哪些
    本文小编为大家详细介绍“javascript继承实现的方式有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“javascript继承实现的方式有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是继承用官...
    99+
    2023-07-05
  • JavaScript继承的三种方法实例
    继承 1. 什么是继承 继承: 首先继承是一种关系,类(class)与类之间的关系,JS中没有类,但是可以通过构造函数模拟类,然后通过原型来实现继承。 继承也是为了数据共...
    99+
    2024-04-02
  • 聊聊JavaScript中实现继承的6种方法
    面试官:“你说说 JavaScript 中实现继承有哪几种方法?”紧张的萌新:“额,class 中用 extends 实现继承,然后...没了...”面试官:“...”······想必绝大部分人一说继承就会想到类中的继承吧,但其实继承可不是...
    99+
    2022-11-22
    javascript
  • 浅谈go中cgo的几种使用方式
    目录最简单的CGO程序源码方式调用C函数内部机制编译和链接参数编译参数:CFLAGS/CPPFLAGS/CXXFLAGS链接参数:LDFLAGS通过静态库的方式调用C函数通过动态库的...
    99+
    2024-04-02
  • 浅谈react路由传参的几种方式
    第一种传参方式,动态路由传参 通过设置link的path属性,进行路由的传参,当点击link标签的时候,会在上方的url地址中显示传递的整个url <Link to='/...
    99+
    2024-04-02
  • 浅谈Springboot2.0防止XSS攻击的几种方式
    目录防止XSS攻击,一般有两种做法:转义 做法的三种实现:转义方法一:注册自定义转换器转义方法二:BaseController转义方法三:Converter在平时做项目代码开发的时候...
    99+
    2022-11-13
    Springboot防止XSS攻击 Springboot防止XSS
  • JavaScript中常见的七种继承及实现
    目录1. 原型链继承2. 借用构造函数继承3. 组合继承4. 原型式继承5. 寄生式继承6. 寄生式组合继承7. class继承1. 原型链继承 原型链继承是 JavaScript ...
    99+
    2023-03-08
    JavaScript实现继承方式 JavaScript继承
  • JavaScript 继承的方方面面:深入浅出
    引言 继承是面向对象编程中的一项基本机制,它允许创建派生类,从基类继承属性和方法。在 JavaScript 中,有两种主要类型的继承:通过原型链和 ES6 中引入的类。本文将深入探索 JavaScript 继承的方方面面,从基础概念到高...
    99+
    2024-02-15
    JavaScript 继承 ES6 原型链
  • Javascript继承关系的实现方法
    本篇内容介绍了“Javascript继承关系的实现方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!说明JavaScript中的继承关系是通...
    99+
    2023-06-20
  • 浅谈Springboot实现拦截器的两种方式
    目录一、拦截器方式1、配置HandlerInterceptor2、注册拦截器3、使用拦截器的坑二、过滤器方式1、实现Filter接口2、使用过滤器需要注意的实现过滤请求有两种方式: ...
    99+
    2024-04-02
  • 浅谈Java几种文件读取方式耗时
    目录BufferedReaderFiles.readAllBytesFiles.linesCommonIO::readFileToString项目中经常会遇到文件读写,不同的读写方式...
    99+
    2023-05-15
    Java 文件读取 Java 文件读取耗时
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作