聊一聊js中的继承
一、简单继承---使用原型赋值的方式继承,将实例化的对象,赋值给子级的原型
父级构造函数
function Parent(param) {
this.name = 'parent'
this.otherName = 'otherName'
this.param = param || 'param'
}
Parent.prototype.sayName = function() {
console.log('this.name :', this.name)
}
子级构造函数
function Son() {
this.name = 'son'
}
Son.prototype = new Parent() // 继承
let newSon1 = new Son()
let newSon2 = new Son() console.log('newSon1 :', newSon1) // newSon1 : Parent { name: 'son' }
// newSon1 : Parent { name: 'parent', otherName: 'otherName' } // newSon1.__proto__ 指向构造函数 Son 的原型 prototype
console.log('newSon1 :', newSon1.__proto__)
// newSon1.__proto__ 指向构造函数 Son 的原型 prototype
// Son 的 prototype 赋值为 new Parent(),所以 Son 的构造函数不是自己,而是 Parent
// newSon1.__proto__.constructor : function Parent() {
// this.name = 'parent'
// this.otherName = 'otherName'
// }
console.log('newSon1.__proto__.constructor :', newSon1.__proto__.constructor) console.log('newSon2 :', newSon2) // newSon1 : Parent { name: 'son' }
// newSon2 : Parent { name: 'parent', otherName: 'otherName' } // newSon2.__proto__ 指向构造函数 Son 的原型 prototype
console.log('newSon2 :', newSon2.__proto__) // 修改 newSon1 继承而来的 otherName 属性, newSon2也发生了变化
newSon1.__proto__.otherName = 'son1-OtherName'
console.log('newSon1.otherName :', newSon1.otherName)
console.log('newSon2.otherName :', newSon2.otherName)

缺点:

所有的实例化对象会共享属性,对于任一个属性的修改,其他的实例化对象都会同步变化
子级的构造函数也不是自己,需要重新指定
二、经典继承---改变this指向到当前的实例化对象
父级构造函数
function Parent() {
this.name = 'parent'
this.otherName = 'otherName'
}
Parent.prototype.sayName = function() {
console.log('this.name :', this.name)
}
子级构造函数
function Son(param) {
Parent.call(this, param) // 继承
}
缺点:
解决了上面提到的属性共享问题
新问题出来了,需要将方法定义在构造函数内部,否则无法被继承,
每实例化一次,构造函数里面的函数方法就创建一次,对资源是一个浪费
三、组合继承
使用call/apply方法进行属性的继承
用原型链继承的方法,继承原来的所有函数方法
父级构造函数
function Parent() {
this.name = 'parent'
this.otherName = 'otherName'
}
Parent.prototype.sayName = function() {
console.log('this.name :', this.name)
}
子级构造函数
function Son(param) {
Parent.call(this, param)
}
Son.prototype = Parent.prototype
Son.prototype.constructor = Son // 修改构造函数为自己
缺点:
因为是使用赋值引用的模式进行原型继承,
如果子级重写父级的某个属性或方法,父级也会发生改变
四、组合继承+深拷贝
父级构造函数
function Parent() {
this.name = 'parent'
this.otherName = 'otherName'
}
Parent.prototype.sayName = function() {
console.log('this.name :', this.name)
}
子级构造函数
function Son(param) {
Parent.call(this, param)
}
深拷贝原型链
deepCopy(Son.prototype, Parent.prototype)
Son.prototype.constructor
= Son // 修改构造函数为自己
function deepCopy(target, obj) {
for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (typeof obj[prop] === 'object') {
target[prop] = Object.prototype.toString.call(obj[prop]) === '[object Array]' ? [] : {}
deepCopy(target[prop], obj[prop])
} else {
target[prop] = obj[prop]
}
}
}
}

谈谈JavaScript中继承方式的更多相关文章

  1. javascript中继承方式及优缺点(一)

    分别介绍原型链继承.call/apply继承(借用构造函数继承).组合继承.原型式继承.寄生式继承.寄生组合式继承 1. 原型链继承 核心:将父类的实例作为子类的原型 function SuperTy ...

  2. javascript中继承方式及优缺点(三)

    文以<JavaScript高级程序设计>上的内容为骨架,补充了ES6 Class的相关内容,从我认为更容易理解的角度将继承这件事叙述出来,希望大家能有所收获. 1. 继承分类 先来个整体印 ...

  3. javascript中继承方式及优缺点(二)

    一.原型链继承 方式1: 原型链继承 (1)流程: ​ 1.定义父类型构造函数. ​ 2.给父类型的原型添加方法. ​ 3.定义子类型的构造函数. ​ 4.创建父类型的对象赋值给子类型的原型. ​ 5 ...

  4. 谈谈javascript中的prototype与继承

    谈谈javascript中的prototype与继承 今天想谈谈javascript中的prototype. 通常来说,javascript中的对象就是一个指向prototype的指针和一个自身的属性 ...

  5. Javascript中继承

    Javascript中继承 构造函数继承 原型继承 call和apply继承 组合继承

  6. javascript 中继承实现方式归纳

    转载自:http://sentsin.com/web/1109.html 不同于基于类的编程语言,如 C++ 和 Java,javascript 中的继承方式是基于原型的.同时由于 javascrip ...

  7. 实现JavaScript中继承的三种方式

    在JavaScript中,继承可以通过三种手法实现原型链继承 使用apply.call方法 对象实例间的继承.     一.原型链继承 在原型链继承方面,JavaScript与java.c#等语言类似 ...

  8. 谈谈javascript中原型继承

    什么是继承?拿来主义:自己没有,别人有,把别人的拿过来使用或者让其成为自己的 如何实现继承的方式 原型继承 混入继承 经典继承 1. 混入继承 由于一个对象可以继承自任意的对象,即:o可以继承自对象o ...

  9. javascript中继承(一)-----原型链继承的个人理解

    [寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...

随机推荐

  1. java的设计模式 - 单例模式

    java 面试中单例模式基本都是必考的,都有最推荐的方式,也不知道问来干嘛.下面记录一下 饿汉式(也不知道为何叫这个名字) public class Singleton { private stati ...

  2. php 获取URL 各部分参数

    URL处理几个关键的函数parse_url.parse_str与http_build_query parse_url() 该函数可以解析 URL,返回其组成部分.它的用法如下: array parse ...

  3. C盘突然报警,空间不足,显示成红色了

    1.清理系统垃圾文件 将如下命令保存到一个bat文件中,执行,删除垃圾文件 @echo off net share c$ /del net share d$ /del net share e$ /de ...

  4. sql面试 查找每个班级的前5名学生(取分类数据的前几条数据)

    关键字PARTITION BY 自己看代码喽~ SELECT * FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY ClassType ORDER BY Sc ...

  5. hadoop wordcout测试

    hadoop wordcout测试 安装好hadoop 环境后,启动HDFS等服务:输密码 1004 start-all.sh 查看启动情况 1006 jps 1007 cd ~ 切换到用户默认目录 ...

  6. linux系统ubuntu18.04安装mysql(5.7)

    本文是参考mysql官网整理而成,顺便把一些遇到的问题记载下来. ①将MySQLAPT存储库添加到系统的软件存储库列表中  ---->下载APT存储库(下载链接)  ---->安装APT存 ...

  7. Django入门之路

    Web框架开发-Django基础之web应用,Http协议 web框架开发-web框架简介,wsgiref模块,DIY一个web框架 web框架开发-Django简介 web框架开发-静态文件配置 w ...

  8. 二。Hibernate 查询 HQL、SQL方式

    hibernate的查询1.HQL方式:所有查询都是根据java对象名来完成,对象名替换表名2.SQL方式:保留原来的sql查询风格3.可以通过设置第一条和最大条数来实现各种数据库的分页查询4.通过B ...

  9. 小A的柱状图

    链接 [https://ac.nowcoder.com/acm/contest/549/H] 题意 [] 分析 很显然你必须找到该高度下往左右找到第一个高度比该位置小的.这个区间的宽*该高度.就当前能 ...

  10. springboot整合Quartz实现定时任务

    1.maven依赖: <!--quartz--> <dependency> <groupId>org.quartz-scheduler</groupId> ...