文档章节

JavaScript继承(三)——组合继承

Bob2100
 Bob2100
发布于 01/26 11:38
字数 695
阅读 14
收藏 1

借用构造函数继承解决了原型链数据共享和无法向超类型传递参数的问题,但自身的缺陷是不能使用超类型原型中定义的方法。组合继承是将原型链继承和借用构造函数继承组合到一起,从而发挥二者之长的一种继承模式,也被称作伪经典继承。背后的思路是使用原型链实现原型属性和方法的继承,使用构造函数来实现实例属性的继承。这样既通过在原型上定义方法实现了函数的复用,又能保证每个实例都有它自己的属性。

下面来看一个例子:

function Human(name) {
  this.name = name;
  this.colors = ['yellow', 'white', 'black'];
}
Human.prototype.sayName = function(){
  return this.name;
}

//call的用法和apply相同,只不过call在传递参数的时候需要把
//参数一一列出,而apply传递的是arguments
function Person(name, age) {
  //构造函数继承属性
  Human.call(this, name);
  this.age = age;
}

//使用原型链继承方法
Person.prototype = new Human();
Person.prototype.constructor = Person;
//定义自己的方法
Person.prototype.sayAge = function(){
  return this.age;
}

//测试使用
var p1 = new Person('Jack', 18);
p1.colors.push('brone');
console.log(p1.colors);//["yellow", "white", "black", "brone"]
console.log(p1.sayName(), p1.sayAge());//Jack 18

var p2 = new Person('Rose', 20);
console.log(p2.colors);//["yellow", "white", "black"]  
console.log(p2.sayName(), p2.sayAge());//Rose 20

在这个例子中首先声明了一个Human函数,然后使用原型模式定义了sayName方法。声明了Person函数,通过构造函数模式继承了Human,但是这只能继承Human中声明的属性,也就是实例属性,没办法继承原型属性和方法,于是紧接着将Person的原型赋值为Human的一个实例,通过原型链实现原型属性和方法的继承,然后添加了一个子类型特有的方法sayName,这就是组合继承。测试使用,结果既可以通过构造函数向超类型传递参数,也没有colors被共享的问题,同时还可以使用超类型原型上定义的方法sayName,可以说非常完美。

组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JavaScript中最常用的继承模式。而且,因为使用了原型链,instanceOfisPrototypeOf也能够识别基于组合继承创建的对象。

© 著作权归作者所有

共有 人打赏支持
Bob2100
粉丝 23
博文 86
码字总数 47062
作品 0
浦东
高级程序员
私信 提问
JavaScript继承(六)——寄生组合式继承

JavaScript继承(三)——组合继承中讲到,组合继承是JavaScript中最常用的继承模式,但是它也有自己的不足之处,现在我们就来剖析它的不足,如下示例: 使用组合继承让继承实际上分为两步:...

Bob2100
02/16
0
0
JavaScript继承(二)——借用构造函数

JavaScript继承(一)——原型链中提出原型链继承的两个问题:一是原型的数据共享问题,二是创建子类型的实例时,不能向父类型的构造函数中传递参数。这两个问题的根源还是在于使用原型模式创...

Bob2100
01/20
0
0
每个JavaScript工程师都应懂的33个概念

摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:stephentian Fundebug经授权转载,版权归原作者所有...

Fundebug
2018/10/30
0
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方...

嗨呀豆豆呢
2018/12/25
0
0
JavaScript开发者应懂的33个概念

简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。 本篇文章是参照 @leonardomso 创立,英文版项目地址在这里。 ...

大灰狼的小绵羊哥哥
2018/10/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

5、redis分布式锁

参考链接:https://www.cnblogs.com/linjiqin/p/8003838.html 一:介绍 实现分布式锁有三种方式:1、数据库乐观锁,2、基于redis,3、基于zookeeper。 redis服务端是单线程操作,完美地避免了...

刘付kin
18分钟前
3
0
OSChina 周日乱弹 —— 我重新说

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享矢野立美的单曲《LOVE Theme from TIGA <M-2>》: 《LOVE Theme from TIGA <M-2>》- 矢野立美 手机党少年们想听歌,请使劲儿戳...

小小编辑
今天
56
5
Java单例模式学习记录

在项目开发中经常能遇见的设计模式就是单例模式了,而实现的方式最常见的有两种:饿汉和饱汉(懒汉)。由于日常接触较多而研究的不够深入,导致面试的时候被询问到后有点没底,这里记录一下学习...

JerryLin123
昨天
10
0
VSCODE 无法调试

VSCODE 无法调试 可以运行 可能的原因: GCC 的参数忘了加 -g

shzwork
昨天
5
0
理解去中心化 稳定币 DAI

随着摩根大通推出JPM Coin 稳定币,可以预见稳定币将成为区块链落地的一大助推器。 坦白来讲,对于一个程序员的我来讲(不懂一点专业经济和金融),理解DAI的机制,真的有一点复杂。耐心看完...

Tiny熊
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部