js继承之组合继承(结合原型链继承 和 借用构造函数继承)
在我的前两篇文章中,我们已经介绍了 js 中实现继承的两种模式:原型链继承和借用构造函数继承。这两种模式都存在各自的缺点,所以,我们考虑是否能将这二者结合到一起,从而发挥二者之长。即在继承过程中,既可以保证每个实例都有它自己的属性,又能做到对一些属性和方法的复用。这样就 perfect 了。
一、回顾借用构造函数继承的缺点
先看我们之前在借用构造函数继承中最后用到的代码:
//父类:人
function Person () {
this.head = '脑袋瓜子';
this.emotion = ['喜', '怒', '哀', '乐']; //人都有喜怒哀乐
this.eat = function () {
console.log('吃吃喝喝');
}
this.sleep = function () {
console.log('睡觉');
}
this.run = function () {
console.log('快跑');
}
}
//子类:学生,继承了“人”这个类
function Student(studentID) {
this.studentID = studentID;
Person.call(this);
} //Student.prototype = new Person(); var stu1 = new Student(1001);
console.log(stu1.emotion); //['喜', '怒', '哀', '乐'] stu1.emotion.push('愁');
console.log(stu1.emotion); //["喜", "怒", "哀", "乐", "愁"] var stu2 = new Student(1002);
console.log(stu2.emotion); //["喜", "怒", "哀", "乐"]
在这段代码中,我们通过借用构造函数继承,保证了 stu1 和 stu2 都有各自的父类属性副本,从而使得各自 emotion 互不影响。但同时带来的问题是,stu1 和 stu2 都拷贝了 Person 类中的所有属性和方法,而在 Person 类中,像 eat ( ), sleep ( ), run ( ) 这类方法应该是公用的,而不需要添加到每个实例上去,增大内存,尤其是这类方法较多的时候。
二、结合使用两种继承模式
所以我们想到,是否能把这些方法挂载到父类的原型对象上去,实现方法复用,然后子类通过原型链继承,就能调用这些方法啦?~
//父类:人
function Person () {
this.head = '脑袋瓜子';
this.emotion = ['喜', '怒', '哀', '乐']; //人都有喜怒哀乐
}
//将 Person 类中需共享的方法放到 prototype 中,实现复用
Person.prototype.eat = function () {
console.log('吃吃喝喝');
}
Person.prototype.sleep = function () {
console.log('睡觉');
}
Person.prototype.run = function () {
console.log('快跑');
}
//子类:学生,继承了“人”这个类
function Student(studentID) {
this.studentID = studentID;
Person.call(this);
} Student.prototype = new Person(); //此时 Student.prototype 中的 constructor 被重写了,会导致 stu1.constructor === Person
Student.prototype.constructor = Student; //将 Student 原型对象的 constructor 指针重新指向 Student 本身 var stu1 = new Student(1001);
console.log(stu1.emotion); //['喜', '怒', '哀', '乐'] stu1.emotion.push('愁');
console.log(stu1.emotion); //["喜", "怒", "哀", "乐", "愁"] var stu2 = new Student(1002);
console.log(stu2.emotion); //["喜", "怒", "哀", "乐"] stu1.eat(); //吃吃喝喝
stu2.run(); //快跑
console.log(stu1.constructor); //Student
首先,我们将 Person 类中需要复用的方法提取到 Person.prototype 中,然后设置 Student 的原型对象为 Person 类的一个实例,这样 stu1 就能访问到 Person 原型对象上的属性和方法了。其次,为保证 stu1 和 stu2 拥有各自的父类属性副本,我们在 Student 构造函数中,还是使用了 Person.call ( this ) 方法。如此,结合原型链继承和借用构造函数继承,就完美地解决了之前这二者各自表现出来的缺点。
如果你觉得文章解决了你的疑惑的话,还请赏我一个推荐哦~ :)
作者不才,文中若有错误,望请指正,避免误人子弟。
文章内容全都参考于《JAVASCRIPT 高级程序设计》第三版)
js继承之组合继承(结合原型链继承 和 借用构造函数继承)的更多相关文章
- JS继承之借用构造函数继承和组合继承
根据少一点套路,多一点真诚这个原则,继续学习. 借用构造函数继承 在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术( ...
- JS学习笔记——JavaScript继承的6种方法(原型链、借用构造函数、组合、原型式、寄生式、寄生组合式)
JavaScript继承的6种方法 1,原型链继承 2,借用构造函数继承 3,组合继承(原型+借用构造) 4,原型式继承 5,寄生式继承 6,寄生组合式继承 1.原型链继承. <script t ...
- Js基础知识(二) - 原型链与继承精彩的讲解
作用域.原型链.继承与闭包详解 注意:本章讲的是在es6之前的原型链与继承.es6引入了类的概念,只是在写法上有所不同,原理是一样的. 几个面试常问的几个问题,你是否知道 instanceof的原理 ...
- javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承
javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...
- JS高阶---继承模式(借用构造函数继承+组合继承)
(1)借用构造函数继承 案例如下: 验证: (2)组合继承 案例如下: 验证如下: 结果如右图所示 . .
- js继承之借用构造函数继承
我的上一篇文章介绍了,原型链继承模式.但是单纯的原型链模式并不能很好地实现继承. 一.原型链的缺点 1.1 单纯的原型链继承最大的一个缺点,来自于原型中包含引用类型的值. 本来,我们没有通过原型链实现 ...
- js语言评价--js 基于哈希表、原型链、作用域、属性类型可配置的多范式编程语言
js 基于哈希表.原型链.作用域.属性类型可配置的多范式编程语言 值类型.引用类型.直接赋值: 原型是以对象形式存在的类型信息. ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值,对 ...
- javascript中继承(二)-----借用构造函数继承的个人理解
本人目录如下: 零.寒暄&回顾 一,借用构造函数 二.事件代理 三,call和apply的用法 四.总结 零.寒暄&回顾 上次博客跟大家分享了自己对原型链继承的理解,想看的同学欢迎猛击 ...
- JavaScript里的原型(prototype), 原型链,constructor属性,继承
① __proto__ 和 constructor 属性是 对象 所独有的. ② prototype 属性是 函数 所独有的. ** JS里函数也是引用类型的对象,所以函数也有 __proto__ 和 ...
随机推荐
- App免费推广途径概要
说在前面的话:免费其实挺花功夫的,所有的营销的前提是产品和服务是值得推荐的. 1.技术操作维度:ASO,SEO, ASO简单介绍:http://baike.baidu.com/subview/1368 ...
- tarjan算法讲解。
tarjan算法讲解. 全网最详细tarjan算法讲解,我不敢说别的.反正其他tarjan算法讲解,我看了半天才看懂.我写的这个,读完一遍,发现原来tarjan这么简单! tarjan算法,一个关 ...
- java线程之线程通信控制
在上篇我们看到,A线程往公共资源库(对象)提供了一条数据,然后B线程从库中提取了数据并打印出来. 实际项目中,我们不可能只往库中提供一条数据,而且库的大小也不会是无穷大的,那么我们就会有这样一 个需求 ...
- HTML编码和CSS编码会遇到的问
http://codeguide.bootcss.com/#html-syntax 参考链接 属性顺序 HTML 属性应当按照以下给出的顺序依次排列,确保代码的易读性. class id, name ...
- 学习Vue.js之vue移动端框架到底哪家强
官网:https://cn.vuejs.org/. 转载:http://www.cnblogs.com/8899man/p/6514212.html Weex 2016年4月21日,阿里巴巴在Qcon ...
- 安装RabbitMQ编译erlang时,checking for c compiler default output file name... configure:error:C compiler cannot create executables See 'config.log' for more details.
checking for c compiler default output file name... configure:error:C compiler cannot create executa ...
- 解决150%DPI下Photoshop不能显示成合适大小的问题
Adobe官方这里一直不给力,只能靠自己动手了. 和解决CHM高分屏显示的步骤差不多: Ctril+R,输入regedit编辑注册表. 进入到 HKEY_LOCAL_MACHINE > SOFT ...
- 学HTTP协议所要知道的基础知识(微总结)
1.网络本质 进行资源共享和信息传输. 2.基于网络的应用程序的本质 就是获取数据和传输数据给用户使用. 3.TCP/IP协议栈工作流程 实体层是不属于TCP/IP协议栈的一层.也就是说TCP/IP协 ...
- 重温《STL源码剖析》笔记 第五章
源码之前,了无秘密 ——侯杰 序列式容器 关联式容器 array(build in) RB-tree vector set heap map priority-queue multiset li ...
- ubantu和虚拟机tools 安装 小问题集结
一.虚拟机 就安装虚拟机而言,个人觉得还是比较简易的,毕竟VMware workstation pro 是一个开源的软件,只要在网上搜索即可,这里我提供一个虚拟机的资源: 链接:http://pan. ...