聊一聊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. Python二级-----------程序冲刺1

    1. 仅使用 Python 基本语法,即不使用任何模块,编写 Python 程序计算下列数学表达式的结果并输出,小数点后保留3位.‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪ ...

  2. 《PHP制作个人博客》之四:分类添加及前端导航数据用php动态调取

    大家好,今天我们接着上一节的全栈营销个人博客制作,上一节我们把博客的模板给加载运行起来.今天我们主要讲解后台模板分类的添加,后台导航的添加,及前台导航的动态调用.一个好的博客,导航很重要,导航就像你网 ...

  3. 25 ,CSS 构造表格

    1. 表格的基础构造 2. 边距和边线应用 3. 隐藏和删除应用 1.  简单表格 table { width:auto; border-collapse:collapse; margin-left: ...

  4. Numpy库的学习(四)

    我们今天继续学习一下Numpy库 接着前面几次讲的,Numpy中还有一些标准运算 a = np.arange(3) print(a) print(np.exp(a)) print(np.sqrt(a) ...

  5. There is already an object named '#xxxx' in the database.

    这个案例是前几天同事遇到的一个案例,在存储过程中"删除"了一个临时表,然后重新创建这个临时表时遇到"There is already an object named 'x ...

  6. app.config的坑

    C# C/S程序一般通过ConfigurationManager类来读取app.config,其中有个坑爹的地方是ConfigurationManager类自带缓存,就如Windows服务来说,除非重 ...

  7. WPF软件开发系统之二——水环境检测Surface触摸屏软件开发

    该系统采用C#.WPF语言开发,开发工具Visual Studio 2015.Blend,环境WIN7系统及以上,适用于PC.Windows触摸屏Surface等设备. 部分截图效果如下: 开发工具环 ...

  8. 网络流 之 P2766 最长不下降子序列问题

    题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...

  9. FLIR 相机采集程序

    https://www.ptgrey.com/Downloads/GetSecureDownloadItem/11048 Grasshopper3 4.1 MP Mono USB3 Vision (C ...

  10. asp.net core 排序过滤分页组件:sieve(2)表达式树的复习

    在Sieve组件中使用了很多关于表达式树的知识,但在我们日常的工作中写表达式树的机会是非常少的,至少在我的编程生涯中没怎么写过表达式树(可能也就是3,4次).所以,为了能够看懂Sieve里面的源代码, ...