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继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...
随机推荐
- SonarQube 跳过指定检查
SonarQube 跳过指定检查 如何让 SonarQube 忽略某些检查规则 环境 演示环境参考前边的文章 SonarQube 扫描 Java 代码 步骤 我们已经扫描一个 Java 项目 有 6 ...
- 比原Bapp红包应用
喜迎国庆期间,比原链在自己的移动端钱包Bycoin(下载地址)和google插件钱byone中推出了红包应用,在国庆期间深受大家好评. 那我们今天就来大概介绍一下比原红包,以及基于比原链开发dapp应 ...
- 关于Springboot配置文件的理解
一.Springboot Springboot是用来简化Spring框架搭建和开发一款框架,可以理解为是一种Spring框架的简化版. 二.如何在IDEA里面初始化Springboot 主要可以分为两 ...
- Python学习笔记之 Python设计思想&设计原则
Python设计思想&设计原则 设计思想 1.封装 数据角度 多种数据合为一种数据 优势:代码可读性高 将数据与行为相关联 例如:电脑(内存,储存空间,...) 行为角度 ...
- 算法面试题:一个List<Student>,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点!
算法面试题:一个List,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点! 解题思路 这是群里某位小伙伴去面试碰到的面试题,从题目本身来看,面试官应该是要考察面试者对泛型 Lis ...
- C#LeetCode刷题-极小化极大
极小化极大篇 # 题名 刷题 通过率 难度 375 猜数字大小 II 23.4% 中等 464 我能赢吗 25.5% 中等 486 预测赢家 40.4% 中等 843 猜猜这个单词 2 ...
- C#LeetCode刷题之#728-自除数(Self Dividing Numbers)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3889 访问. 自除数 是指可以被它包含的每一位数除尽的数. 例如 ...
- Vuex mapState的基本使用
mapState把Store中的state映射到组件中的计算属性 Store文件 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) ...
- 微软看上的Rust 语言,安全性真的很可靠吗
摘要:近几年,Rust语言以极快的增长速度获得了大量关注.其特点是在保证高安全性的同时,获得不输C/C++的性能.在Rust被很多项目使用以后,其实际安全性表现到底如何呢? 近几年,Rust语言以极快 ...
- MySQL执行文件中的SQL
连接进入MySQL服务, 使用source ${文件名}执行. 末尾不能带分号.