JavaScript寄生组合式继承实例详解


Posted in Javascript onJanuary 06, 2018

本文实例讲述了JavaScript寄生组合式继承。分享给大家供大家参考,具体如下:

其实《JavaScript高级程序设计》这本书中已经有完整代码了,只要把代码读懂就知道这个继承是怎么回事。

首先,在js中,给对象定义属性有两种方式:

//通过执行构造函数设置属性
function A(){
  this.a = 1;
}
//通过原型设置属性
A.prototype.b = 1;

所以:

一个类Sub要继承另一个类Super,需要继承父类的prototype下的属性,还要执行一下父类的构造函数。

一个类Sub要继承另一个类Super,既要通过原型链实现对原型属性和方法的继承,又要通过在子类构造函数内调用父类构造函数实现对实例属性的继承

1. 继承prototype下的属性

上面可以看到,Super类的prototype下的属性是没有被继承的,因此下面还需要继承这一部分。

直接「=」肯定不行,因为Sub.prototype中修改属性后,不能影响Super.prototype里面的对象,即不能Sub.prototype=Super.prototype

首先写一个创建对象副本的方法

function object(o){
  function A(){}
  A.prototype = o
  var ox = new A()
  return ox
}

上面的函数得到的对象ox,拥有了对象o的全部属性(在原型链上),而修改ox的属性,不会影响到o,相当于把o复制了一份。

原型式继承就是上面的“object”函数,在很多类库源码中都能发现它的身影

简单而言,原型式继承就是不用实例化父类了,直接实例化一个临时副本实现了相同的原型链继承。(即子类的原型指向父类副本的实例从而实现原型共享)

tips:总所周知,原型链继承是子类的原型指向父类的实例从而实现原型共享,而原型式继承是子类的原型指向父类副本的实例从而实现原型共享

ECMAScirpt 5通过新增Object.create()方法规范化了原型式继承。

使用object方法,就可以将Super.prototype的属性「复制」到Sub.prototype上了,当然这儿还需要修正一下constructor的指向。

function inherit(subType,superType){
 var prototype=Object.create(superType.prototype);
 prototype.constructor=subType;
 subType.prototype=prototype;
}

2. 分别执行父类和子类的构造函数,继承这部分下的属性:

//父类
function Super(){
this.sss=1
}
//子类
function Sub(){
//arguments是Sub收到的参数,将这个参数传给Super
Super.apply(this, arguments)
}
//实例
sub = new Sub()

Super.apply(this, arguments)这一句,将Super类作为一个普通函数来执行,但是Super类的this被换成了Sub类的this,Sub收到的参数也传给了Super

最后执行结果相当于sub.sss=1

附上各种继承方式的特点和优缺点

曾经一段时间因为javascript关于类实现继承的不规范,导致各种各样实现继承的代码;而实际上不管代码怎么变,继承都基于两种方式:

1.通过原型链,即子类的原型指向父类的实例从而实现原型共享。
2.借用构造函数,即通过js的apply、call实现子类调用父类的属性、方法;

原型链方式可以实现所有属性方法共享,但无法做到属性、方法独享(例如Sub1修改了父类的函数,其他所有的子类Sub2、Sub3...想调用旧的函数就无法实现了);

借用构造函数除了能独享属性、方法外还能在子类构造函数中传递参数,但代码无法复用。总体而言就是可以实现所有属性方法独享,但无法做到属性、方法共享(例如,Sub1新增了一个函数,然后想让Sub2、Sub3...都可以用的话就无法实现了,只能Sub2、Sub3...各自在构造函数中新增)。

组合继承就是把以上两种继承方式一起使用,把共享的属性、方法用原型链继承实现,独享的属性、方法用借用构造函数实现,所以组合继承几乎完美实现了js的继承;为什么说是“几乎”?因为认(dan)真(teng)的geek们发现组合继承有一个小bug,实现的时候调用了两次超类(父类),性能上不合格啊有木有!怎么解决呢?于是“寄生继承”就出来了。

寄生继承(原型式继承)就是不用实例化父类了,直接实例化一个临时副本实现了相同的原型链继承。(即子类的原型指向父类副本的实例从而实现原型共享)

“寄生组合继承”用了“寄生继承”修复了“组合继承”的小bug,从而让js完美实现继承了。

实例代码:

function SuperType(name,colors){
  this.name=name;
  this.colors=colors;
}
SuperType.prototype.getSuperProperty=function(){ return this.name; }
function SubType(job,name,colors){
  SuperType.call(this,name,colors);
  this.job=job;
}
SubType.prototype.getSubPrototype=function(){ return this.job; }
function inherit(subType,superType){
  var prototype=Object.create(superType.prototype);
  prototype.constructor=subType;
  subType.prototype=prototype;
}
inherit(SubType,SuperType);
var instance=new SubType("doctor","John",["red","green"]);
console.log(instance.getSubPrototype());  //输出"doctor"
console.log(instance.getSuperProperty());  //输出"John",成功调用在父类原型定义的方法

属性继承代码是SuperType.call(this,name,colors);

原型继承代码是inherit(SubType,SuperType);

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JavaScript中的私有成员
Sep 18 Javascript
jQuery选择器中含有空格的使用示例及注意事项
Aug 25 Javascript
Javascript中匿名函数的多种调用方式总结
Dec 06 Javascript
javascript中indexOf技术详解
May 07 Javascript
js仿淘宝和百度文库的评分功能
May 15 Javascript
基于jQuery实现仿百度首页选项卡切换效果
May 29 Javascript
vue 2.0组件与v-model详解
Mar 27 Javascript
NW.js 简介与使用方法
Feb 01 Javascript
vue和webpack安装命令详解
Jun 15 Javascript
React 组件渲染和更新的实现代码示例
Feb 21 Javascript
JavaScript数据结构与算法之二叉树添加/删除节点操作示例
Mar 01 Javascript
解决vue数据不实时更新的问题(数据更改了,但数据不实时更新)
Oct 27 Javascript
基于jquery trigger函数无法触发a标签的两种解决方法
Jan 06 #jQuery
JS实现非首屏图片延迟加载的示例
Jan 06 #Javascript
jQuery中库的引用方法
Jan 06 #jQuery
基于JavaScript中标识符的命名规则介绍
Jan 06 #Javascript
js生成word中图片处理方法
Jan 06 #Javascript
详解webpack中的hash、chunkhash、contenthash区别
Jan 05 #Javascript
浅谈webpack对样式的处理
Jan 05 #Javascript
You might like
上海牌131型七灯四波段四喇叭一级收音机
2021/03/02 无线电
linux系统下php安装mbstring扩展的二种方法
2014/01/20 PHP
PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】
2017/01/13 PHP
PHP利用二叉堆实现TopK-算法的方法详解
2017/04/24 PHP
利用PHP扩展Xhprof分析项目性能实践教程
2018/09/05 PHP
JS在IE和FireFox之间常用函数的区别小结
2010/03/12 Javascript
lyhucSelect基于Jquery的Select数据联动插件
2011/03/29 Javascript
jQuery实现按钮只点击一次后就取消点击事件绑定的方法
2015/06/26 Javascript
cocos2dx骨骼动画Armature源码剖析(一)
2015/09/08 Javascript
微信小程序 页面跳转传递值几种方法详解
2017/01/12 Javascript
jQuery实现简单日期格式化功能示例
2017/09/19 jQuery
webpack打包js文件及部署的实现方法
2017/12/18 Javascript
vuex 使用文档小结篇
2018/01/11 Javascript
集成vue到jquery/bootstrap项目的方法
2018/02/10 jQuery
vue-cli3.0 脚手架搭建项目的过程详解
2018/10/19 Javascript
JS中超越现实的匿名函数用法实例分析
2019/06/21 Javascript
element ui分页多选,翻页记忆的实例
2019/09/03 Javascript
javascript实现雪花飘落效果
2020/08/19 Javascript
Python使用plotly绘制数据图表的方法
2017/07/18 Python
Python模块的加载讲解
2019/01/15 Python
python实现nao机器人身体躯干和腿部动作操作
2019/04/29 Python
PyQt5高级界面控件之QTableWidget的具体使用方法
2020/02/23 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
python利用蒙版抠图(使用PIL.Image和cv2)输出透明背景图
2020/08/04 Python
流行文化收藏品:Sideshow(DC漫画,星球大战,漫威)
2019/03/17 全球购物
Theflamel意大利:女士奢华服装、鞋子和配件
2020/01/11 全球购物
党校自我鉴定范文
2013/10/02 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
迟到检讨书400字
2014/01/13 职场文书
爱国演讲稿400字
2014/05/07 职场文书
奉献演讲稿范文
2014/05/21 职场文书
2014市府办领导班子“四风问题”对照检查材料思想汇报
2014/09/24 职场文书
2014年社区计生工作总结
2014/11/18 职场文书
民事和解协议书格式
2014/11/29 职场文书
2016年感恩教师节活动总结
2016/04/01 职场文书
python调试工具Birdseye的使用教程
2021/05/25 Python