文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2023-05-17 08:38

关注

当前需求: 实现 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构造函数满足以下条件

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

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

方式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

缺点

借用构造函数继承

方式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

优点

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

缺点

寄生式继承

思路

属性的继承已经解决, 通过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实现方法的继承

image.png

附: 扩充createObject

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

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

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

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

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯