有父子两个函数,代表两个类:

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中写继承的方式的更多相关文章

  1. JS中的继承实现方式

    第一种:通过prototype来实现 prototype.html <!DOCTYPE html><html lang="en"><head> ...

  2. js中实现继承的几种方式

    首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...

  3. JS中的继承(上)

    JS中的继承(上) 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(prototype)的,对js的原型感兴趣的同学,可以了解一下我之 ...

  4. js中的继承和重载

      js中有三种继承方式:一.通过原型(prototype)实现继承 二.借用构造函数式继承,可分为通过call()方法实现继承和通过apply()方法实现继承 仅仅通过原型继承我们可以发现在实例化子 ...

  5. html css <input> javaScript .数据类型 JS中的函数编写方式 BOM总结 DOM总结

    Day27  html css div 块标签. 特点: 独占一行,有高度和宽度 span 行元素. 特点:在同一行显示,当前行满了自动去下一行显示. 不识别高度和宽度 1.1.1.1 2.输入域标签 ...

  6. 基础篇:1.JavaScript运行在html中,引用有几种方式?—— 6.js中常用的输出方式?

    书接上文,上文提到若干条JavaScript的基础性知识,大部分都是一些概念性的东西,本着认真严谨的态度,我们要认真对待,有些条目的问题是某个知识点的周边延伸,为节约篇幅,就一起整理了,如有描述不对的 ...

  7. Javascript中实现继承的方式

    js中实现继承和传统的面向对象语言中有所不同:传统的面向对象语言的继承由类来实现,而在js中,是通过构造原型来实现的,原型与如下几个术语有关: ①构造函数:在构造函数内部拥有一个prototype属性 ...

  8. 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承

    ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...

  9. JS中的继承(下)

    JS中的继承(下) 在上一篇 JS中的继承(上) 我们介绍了3种比较常用的js继承方法,如果你没看过,那么建议你先看一下,因为接下来要写的内容, 是建立在此基础上的.另外本文作为我个人的读书笔记,才疏 ...

随机推荐

  1. SonarQube 跳过指定检查

    SonarQube 跳过指定检查 如何让 SonarQube 忽略某些检查规则 环境 演示环境参考前边的文章 SonarQube 扫描 Java 代码 步骤 我们已经扫描一个 Java 项目 有 6 ...

  2. 比原Bapp红包应用

    喜迎国庆期间,比原链在自己的移动端钱包Bycoin(下载地址)和google插件钱byone中推出了红包应用,在国庆期间深受大家好评. 那我们今天就来大概介绍一下比原红包,以及基于比原链开发dapp应 ...

  3. 关于Springboot配置文件的理解

    一.Springboot Springboot是用来简化Spring框架搭建和开发一款框架,可以理解为是一种Spring框架的简化版. 二.如何在IDEA里面初始化Springboot 主要可以分为两 ...

  4. Python学习笔记之 Python设计思想&设计原则

    Python设计思想&设计原则 设计思想 1.封装 数据角度 多种数据合为一种数据 优势:代码可读性高            将数据与行为相关联 例如:电脑(内存,储存空间,...) 行为角度 ...

  5. 算法面试题:一个List<Student>,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点!

    算法面试题:一个List,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点! 解题思路 这是群里某位小伙伴去面试碰到的面试题,从题目本身来看,面试官应该是要考察面试者对泛型 Lis ...

  6. C#LeetCode刷题-极小化极大

    极小化极大篇 # 题名 刷题 通过率 难度 375 猜数字大小 II   23.4% 中等 464 我能赢吗   25.5% 中等 486 预测赢家   40.4% 中等 843 猜猜这个单词   2 ...

  7. C#LeetCode刷题之#728-自除数(Self Dividing Numbers)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3889 访问. 自除数 是指可以被它包含的每一位数除尽的数. 例如 ...

  8. Vuex mapState的基本使用

    mapState把Store中的state映射到组件中的计算属性 Store文件 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) ...

  9. 微软看上的Rust 语言,安全性真的很可靠吗

    摘要:近几年,Rust语言以极快的增长速度获得了大量关注.其特点是在保证高安全性的同时,获得不输C/C++的性能.在Rust被很多项目使用以后,其实际安全性表现到底如何呢? 近几年,Rust语言以极快 ...

  10. MySQL执行文件中的SQL

    连接进入MySQL服务, 使用source ${文件名}执行. 末尾不能带分号.