JS中写继承的方式
有父子两个函数,代表两个类:
var parent = function(){}
var child = function(){}
一、直接继承
child.prototype = new parent();
child.prototype.constructor = child;
这种方式有风险,说是如果parent中有this,然后parent在其他地方给this混入了其他东西,child的继承原型中就会莫名多了其他不属于他们的东西,这样不好。。。
-----------------
2020.04.24,来针对上面这种继承方式的风险进行说明。
假设parent的构造函数中包含了很多属性,其中包括引用类型的,也就是这样的:
function Parent(name,age){
this.name=name
this.age=age
this.arr=[]
this.obj={}
}
其中arr和obj就是风险,如果设置child.prototype=new Parent(name,age),child.prototype.constructor=child,那么接下来child的所有实例化对象都会包含这两个arr,obj,并且引用地址都是同一个,那么问题就来了,假设有两个Child的实例化对象,var child1=new Child(),var child2=new Child(),如果child1.arr.push(xxxx),或者child1.obj.xxx=xxxx,那么完蛋了,child2拿到的arr和obj都会受到影响,拿到的都是受到影响之后的对象。
化解这种风险的方法:也可以在Child的构造函数中,写自己的特有的属性之前调用一下Parent.call(this),这样就可以将父类的属性变成自己的属性了,而不再是共享在原型中的了,这样操作以后,哪怕再写Child.prototype=new Parent()也不怕了,因为继承关系,子类属性已经在了,哪怕原型中有同名属性也不怕。那么就怕使用delete之后再改原型对应的属性,那么还是有风险【捂脸】。
而下面的借助中间空函数的做法,就能完全避免这种问题,因为空函数本身不引入任何this的东西。
-----------------
二、借助中间空函数
var nop = function(){}
nop.prototype = parent.prototype;
child.prototype = new nop();
child.prototype.constructor = child;
空函数的办法,就解决了第一种方法的隐患,空函数中没有任何this相关的隐患,如果封装在一个继承函数里,函数外面根本拿不到里面的这个空函数,安全可靠。
三、Object.setPrototypeOf
Object.setPrototypeOf(child.prototype,parent.prototype);
该方法是ES6新增的设置原型的方法,它可以直接关联两个对象,而不需要重新将child的constructor手动拉回,简单方便,实在是原型继承,必备良药。
四、Object.create
child.prototype = Object.create(parent.prototype);
child.prototype.constructor = child;
此种方法也是安全可靠,使用方便无隐患,缺点也是需要手动设置一下自己的constructor.
JS中写继承的方式的更多相关文章
- JS中的继承实现方式
第一种:通过prototype来实现 prototype.html <!DOCTYPE html><html lang="en"><head> ...
- js中实现继承的几种方式
首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...
- JS中的继承(上)
JS中的继承(上) 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(prototype)的,对js的原型感兴趣的同学,可以了解一下我之 ...
- js中的继承和重载
js中有三种继承方式:一.通过原型(prototype)实现继承 二.借用构造函数式继承,可分为通过call()方法实现继承和通过apply()方法实现继承 仅仅通过原型继承我们可以发现在实例化子 ...
- html css <input> javaScript .数据类型 JS中的函数编写方式 BOM总结 DOM总结
Day27 html css div 块标签. 特点: 独占一行,有高度和宽度 span 行元素. 特点:在同一行显示,当前行满了自动去下一行显示. 不识别高度和宽度 1.1.1.1 2.输入域标签 ...
- 基础篇:1.JavaScript运行在html中,引用有几种方式?—— 6.js中常用的输出方式?
书接上文,上文提到若干条JavaScript的基础性知识,大部分都是一些概念性的东西,本着认真严谨的态度,我们要认真对待,有些条目的问题是某个知识点的周边延伸,为节约篇幅,就一起整理了,如有描述不对的 ...
- Javascript中实现继承的方式
js中实现继承和传统的面向对象语言中有所不同:传统的面向对象语言的继承由类来实现,而在js中,是通过构造原型来实现的,原型与如下几个术语有关: ①构造函数:在构造函数内部拥有一个prototype属性 ...
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...
- JS中的继承(下)
JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...
随机推荐
- CI4框架应用六 - 控制器应用
这节我们来分析一下控制器的应用,我们看到系统提供的控制器都是继承自一个BaseController,我们来分析一下这个BaseController的作用 use CodeIgniter\Control ...
- mqtt第一次接触
一.接触的原因 公司最近要求接手关于系统集成道闸的部分,其中系统和第三方系统是通过mqtt进行交互的.所以提前了解一下mqtt的基础概念. 二.mqtt的基本概念 1. mqtt的定义 Message ...
- 005_go语言中的for循环
代码演示 package main import "fmt" func main() { i := 1 for i <= 3 { fmt.Println(i) i = i + ...
- Fault-Tolerance, Fast and Slow: Exploiting Failure Asynchrony in Distributed Systems
本文(OSDI 18')主要介绍一种新的副本复制协议:SAUCR(场景可感知的更新与故障恢复).它是一种混合的协议: 在一定场景(正常情况)下:副本复制的数据缓存在内存中. 故障发生时(多个节点挂掉, ...
- Spring Cloud 之服务注册中心高可用
服务注册中心高可用 服务注册中心 eureka-server 高可用实施 版本 Spring Boot 版本 # Spring Boot 版本: <parent> <groupId& ...
- 滴滴推理引擎IFX:千万规模设备下AI部署实践
桔妹导读:「滴滴技术」将于本月开始,联合各技术团队为大家带来精彩分享.你想了解的技术干货,深度专访,团队及招聘将于每周三与你准时见面.本月为「滴滴云平台事业群分享月」,在今天的内容中,云平台事业群-机 ...
- .NetCore(Avalonia) 项目dll混淆,Ubuntu 或者deepin操作系统 deb安装包解压,重新打包
.NetCore(Avalonia) 项目dll混淆,deb安装包解压,重新打包 本文分为两部分,一部分是介绍使用 DotNetReactor6.0 及以上版本混淆.netcore项目的dll. 另一 ...
- 看DLI服务4核心如何提升云服务自动化运维
摘要:今天我们来说说DLI是如何实现监控告警来提升整体运维能力,从而为客户更好的提供Serverless的DLI. DLI是支持多模引擎的Serverless大数据计算服务,免运维也是其作为Serve ...
- Typora markdown代码块显示序号
打开偏好设置,找到代码块 打开显示行号 然后关闭Typora重新打开 此时代码块就有行号了
- GitHub 热点速览 Vol.33:听说程序员都是颜控?
作者:HelloGitHub-小鱼干 摘要:GitHub上面除了很多有趣的项目,也有很多高颜值的项目,比如:图片共享网站 Unsplash 开源的 Dataset,提供了两百多张高颜值美照.Heroi ...