原来JS可以这么实现继承

news2024/11/16 5:33:21

当我们在编写代码的时候,有一些对象内部会有一些方法(函数),如果将这些函数在构造函数内部声明会导致内存的浪费,因为实例化构造函数得到不同的实例对象,其内部都有同一个方法,但是占据了不同的内存,就存在内存浪费问题。于是乎我们就需要用到继承。

什么是继承?

通过某种方式让一个对象可以访问到另一个对象中属性和方法,我们将这种方法称之为继承(inheritance)

如果一个类B继承自另一个类A,就把B称之为A的子类,A称之为B的父类或者超类

如何实现继承?

1、原型链继承

// 原型链的继承
SuperType.prototype.getSuperValue = function () {return this.property;
}
function SuperType() {this.property = true
}

Type.prototype = new SuperType();

function Type() {this.typeproperty = false
}

console.log(Type.prototype);

var instance = new Type()

console.log(instance.getSuperValue());// true 

让SuperType的实例对象赋给Type的原型,Type就能继承到SuperType的属性和方法

优点:原型链继承容易上手,书写简单,父类可以复用,被多个子类继承。

缺点:会在子类实例对象上共享父类所有的引用类型实例属性,(子类改不动父类的原始类型),更改一个子类的引用属性,其他子类均受影响;子类不能改父类传参。

2、经典继承(伪造对象)

// 经典继承
SuperType.prototype.name = '寒月十九'

function SuperType(age) {this.color = ['red', 'green', 'blue'],this.age = age
}

function Type(age) {SuperType.call(this,age)
}

var instance = new Type(18)
console.log(instance);
console.log(instance.color); 

经典继承就是借助this的显示绑定,将SuperType的指向绑定到Type身上,使得我们可以直接访问到SuperType身上的属性。

优点:解决了原型链继承子类不能向父类传参的问题和原型共享的问题。

缺点:方法不能复用;子类继承不到父类原型上的属性,只能继承到父类实例对象上的属性。

3、组合继承(原型链继承 + 经典继承)

// 组合继承 (伪经典继承)
SuperType.prototype.sayName =function() {console.log(this.name);
}

function SuperType(name) {this.name = name,this.color = ['red', 'green', 'blue']
}
function Type(age,name) {this.age = ageSuperType.call(this,name)
}

Type.prototype = new SuperType()
Type.prototype.constructor = Type//Type.prototype被替换了,所以要补充一个constructor属性,指向自身,这样new Type得到的实例对象就有constructor属性

Type.prototype.sayAge = function() {console.log(this.age)
}

var instance = new Type(20,'寒月十九');
instance.sayAge(); 

组合继承就是将上面两种继承方式结合起来,先将SuperType的this指向显示绑定到Type,然后再替换Type的原型,再添加上构造器属性指向自身,使得new Type()得到的实例对象就具备构造属性,并且可以继承到SuperType的属性。

优点:解决了原型链继承和经典继承的缺点造成的影响。

缺点:每一次都会调用两次父类的构造函数,一次是在创建子类原型上,另一次是在子类构造函数内部。

4、原型式继承

(1)借助构造函数实现对象的继承

// 原型式继承
function object(obj) {function newFn() {}newFn.prototype = obj;return new newFn();
};
var person = {name: '寒月十九',age: 20,like: {sport: 'coding'}
};
let newObj = object(person); 

(2)Object.create()

var person = {name: '寒月十九',age: 20,like: {sport: 'coding'}
};
let newPerson = Object.create(person,{sex: 'boy'}); 

优点:不需要单独构建构造函数。

缺点:属性中的引用地址会在相关对象中共享。

5、寄生式继承

function createPerson(original) {var clone = Object.create(original)clone.say = function() {// 增强这个对像console.log('hello');}return clone;
};
var person = {name: '寒月十九',age: 20,like: {sport: 'coding'}
};
let newPerson =createPerson(person); 

寄生式继承是原型式继承的加强版,它结合原型式继承和工厂模式,创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象。

优点:上手简单,不用单独创建构造函数。

缺点:寄生式继承给对象添加函数会导致函数难以重用,因此不能做到函数复用而效率降低;引用类型的属性始终都会被继承所共享。

寄生组合式继承

// 寄生组合式继承
SuperType.prototype.sayName = function() {console.log(this.name);
};
SuperType.prototype.like = {a: 1,b: 2
};
function SuperType(name) {this.name = name;this.colors = ['red', 'blue', 'green']
};

function Type(name, age) {this.age = age;SuperType.call(this, name);
}

var anotherPrototype = Object.assign(Type.prototype, SuperType.prototype);
// anotherPrototype.constructor = Type

Type.prototype = anotherPrototype; // new SuperType() 

寄生组合继承是为降低父类构造函数的开销。通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。

优点:高效,只调用一个次父构造函数,不会在原型上添加多余的属性,原型链还能保持不变;开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

缺点:代码较复杂。

class类继承

class Parent{constructor(name) {this.name = name;this.hobbies = ["running", "basketball", "writting"];}getHobbies() {return this.hobbies;}static getCurrent() {// 静态方法,只能类本身调用console.log(this);}
}

class Child extends Parent {constructor(name) {super(name);}
}

var c1 = new Child('寒月十九');
var c2 = new Child('十九'); 

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【unity】开发rts 4 放置建筑进地图;创建单位;单位移动;单位生产者

一 放置建筑进地图 1 GameManage,slot faction阵营插槽, 新建筑拖进secne,便于管理,在实例栏将建筑放在factions下 inital faction entitys,(也可带上cam look at) 添加新建筑上 此时测试&a…

大专生学云计算,工作好找吗?

当然可以找到工作。云计算行业整体是处理高速成长期,市场规模以每年30%的速度增长,市场的扩张意味着需要更多的技术人才支撑,据统计云计算未来五年人才缺口将达到150万。 目前企业对于学历的要求并不高,基本大专及以上都可以的。…

基于神经网络(RBF)补偿的双关节机械手臂自适应控制

目录 前言 1.双关节机械手臂模型 1.1 实际模型 1.2 名义模型 2. 控制律设计 3. 神经网络补偿自适应律设计 3.1自适应律① 3.2自适应律② 4. 仿真分析 4.1仿真模型 4.2 仿真结果 4.3 小结 5学习问题 前言 所谓的补偿可以简单的理解为:将扰动的模型估计出…

【C++】开散列实现unordered_map与unordered_set的封装

本文主要介绍unordered_map与unordered_set的封装,此次封装主要用上文所说到的开散列,通过开散列的一些改造来实现unordered_map与unordered_set的封装 文章目录一、模板参数二、string的特化三、正向迭代器四、构造与析构五、[]的实现六、unordered_map的实现七、u…

MySQL安装教程

目录 一、认识MySQL 二、为什么要选用MySQL 三、关于MySQL8.0 四、安装步骤 一、认识MySQL 1、MySQL是一个开放源码的关系型数据库管理系统,将数据保存再不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。 …

【java基础】接口(interface)

文章目录基础介绍接口的定义关于接口字段和方法的说明使用接口抽象类和接口接口方法冲突的一些说明方法相同名称和参数,返回值相同方法名称相同,参数不同,返回值相同方法返回值不同,名称参数相同方法完全相同,一个有默…

中文预训练大模型—文心Ernie技术原理

文心Ernie技术原理 一、背景技术 Ernie是基于Bert模型进行改进,基本模型是Transformer,Bert完成的预训练任务是:完形填空(通过基本语言单元掩码);上下句预测。 Bert模型的缺陷是:只能捕获局部…

关于Charles抓包

目录 抓包的原理 抓包的步骤 1. 下载Charles 2. PC抓HTTPS协议的包 3. 移动端抓包步骤 证书的原理 抓包的原理 抓包的软件非常多,其实底层逻辑充当了一个中间人代理的角色来对HTTPS进行抓包,结合日常自己用的Charles做一个记录。首先先了解抓包的原…

RT-Thread内核学习笔记

文章目录RT-Thread一、线程1. 线程定义2. 线程栈3. 线程函数 rt_thread_entry()4. 线程控制块 struct rt_thread5. 线程初始化 rt_thread_init()6. 就绪列表7. 调度器二、对象容器1. 对象:所有的数据结构都是对象2. 容器:每当创建一个对象,就…

腾讯云GPU游戏服务器/云主机租用配置价格表出炉!

用于游戏业务的服务器和普通云服务器和主机空间是不同的,游戏服务器对于硬件的配置、网络带宽有更大的要求,一般游戏服务器根据不同的配置和适用场景会有十几元一小时到几十元一小时,而且可以根据不同的按量计费。而普通的云服务器可能需要几…

【技术分享】配置802.1x 本地认证

实验需求 PC1(10.10.10.2/30)直接连接到RouterA的Eth2/0/1端口,RouterA的VLANIF10接口IP地址10.10.10.1/30(为PC1上的网关IP地址),配置802.1x协议进行访问控制,认证方式采用本地认证。 实验步骤 RouterA的配置 V200R00…

Impala 在网易大数据的优化和实践

导读: 网易大数据平台的底层数据查询引擎,选用了 Impala 作为 OLAP 查询引擎,不但支撑了网易大数据的交互式查询与自助分析,还为外部客户提供了商业化的产品与服务。今天将为大家分享下 Impala 在网易大数据的优化和实践。 01 Im…

qnx的spi记录

https://www.cnblogs.com/schips/p/protocol_spi_about.html (主要)https://www.zhihu.com/question/308406342/answer/2901148391https://www.bbsmax.com/A/lk5aa4Pm51/ (有基础测试代码)https://baijiahao.baidu.com/s?id17460…

聚焦技术前沿 引领行业未来 | 第四届OpenI/O 启智开发者大会深度学习与大模型产业应用专场论坛顺利举办!

为探索人工智能的重要发展方向,深入了解大模型、深度学习领域,推动人工智能的快速发展,2月24日,第四届启智开发者大会以“引领前沿技术,推动产业升级”为主题的“深度学习与大模型产业应用专场”在深圳人才研修院智汇中…

数学知识(算法模板)

数学知识 文章目录数学知识一、质数一、试除法判定质数二、试除法分解质因数三、朴素筛法求素数四、线性筛法求素数二、约数一、试除法求所有约数二、约数个数约数之和三、欧几里得算法三、欧拉函数一、欧拉函数的定义二、筛法求欧拉函数四、快速幂一、快速幂二、快速幂求逆元扩…

Vue中rules表单验证,表单必填*显示位置不对,*显示位置错误

<el-form :model"ruleForm" :rules"rules" ref"ruleForm"><el-form-item label"名称" prop"name"><el-input v-model"ruleForm.name"></el-input></el-form-item> </el-form>…

.NET 使用NLog增强日志输出

引言 不管你是开发单体应用还是微服务应用&#xff0c;在实际的软件的开发、测试和运行阶段&#xff0c;开发者都需要借助日志来定位问题。因此一款好的日志组件将至关重要&#xff0c;在.NET 的开源生态中&#xff0c;目前主要有Serilog、Log4Net和NLog三款优秀的日志组件&…

少儿编程 电子学会图形化编程等级考试Scratch一级真题解析(判断题)2022年12月

2022年12月scratch编程等级考试一级真题 判断题(共10题,每题2分,共20分) 26、可以通过四种方式添加新角色(不包括复制已有角色):选择一个角色、绘制、随机、上传角色 答案:对 考点分析:考查角色添加的方式,角色添加四种方式分别为题目给出的四种,所以正确 27、角…

分布式事务总结

1. 分布式事务产生的背景 1.1 数据库水平拆分 对于大部分的业务而言&#xff0c;在起步阶段&#xff0c;为了快速上线&#xff0c;一般都是单库单表的。但是随着业务的扩张&#xff0c;数据量也随着扩增&#xff0c;单库的性能逐渐变差&#xff0c;就会有数据库的单点压力。因…

大数据常见术语

大数据常见术语一览 主要内容包含以下&#xff08;收藏&#xff0c;转发给你身边的朋友&#xff09; 雪花模型、星型模型和星座模型 事实表 维度表 上钻与下钻 维度退化 数据湖 UV与PV 画像 ETL 机器学习 大数据杀熟 SKU与SPU 即席查询 数据湖 数据中台 ODS&#xff0c;DWD&…