JS继承之借用构造函数继承和组合继承


Posted in Javascript onSeptember 07, 2016

借用构造函数继承 

在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术(有时候也叫做伪造对象或经典继承)。这种技术的基本思想相当简单,即在子类型构造函数的内部调用超类型构造函数。 

基本模式

function SuperType(){
 this.colors = ["red", "blue", "green"];
}
function SubType(){
  //继承了SuperType
 SuperType.call(this);
}

var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green"

基本思想 

借用构造函数的基本思想就是利用call或者apply把父类中通过this指定的属性和方法复制(借用)到子类创建的实例中。因为this对象是在运行时基于函数的执行环境绑定的。也就是说,在全局中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。call 、apply方法可以用来代替另一个对象调用一个方法。call、apply 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

 

所以,这个借用构造函数就是,new对象的时候(注意,new操作符与直接调用是不同的,以函数的方式直接调用的时候,this指向window,new创建的时候,this指向创建的这个实例),创建了一个新的实例对象,并且执行SubType里面的代码,而SubType里面用call调用了SuperTyep,也就是说把this指向改成了指向新的实例,所以就会把SuperType里面的this相关属性和方法赋值到新的实例上,而不是赋值到SupType上面。所有实例中就拥有了父类定义的这些this的属性和方法。 

优势 

相对于原型链而言,借用构造函数有一个很大的优势,即可以在子类型构造函数中向超类型构造函数传递参数。因为属性是绑定到this上面的,所以调用的时候才赋到相应的实例中,各个实例的值就不会互相影响了。 

例如: 

function SuperType(name){
this.name = name;
}
function SubType(){
//继承了SuperType,同时还传递了参数
SuperType.call(this, "Nicholas");
//实例属性
this.age = 29;
}
var instance = new SubType();
alert(instance.name); //"Nicholas";
alert(instance.age); //29

劣势 

如果仅仅是借用构造函数,那么也将无法避免构造函数模式存在的问题——方法都在构造函数中定义,因此函数复用就无从谈起了。而且,在超类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。考虑到这些问题,借用构造函数的技术也是很少单独使用的。 

组合继承 

组合继承(combination inheritance),有时候也叫做伪经典继承。是将原型链和借用构造函数的技术组合到一块,从而发挥二者之长的一种继承模式。 

基本思想 

思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。 

基本模型

function SuperType(name){
 this.name = name;
 this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
  alert(this.name);
};
function SubType(name, age){
//继承属性
 SuperType.call(this, name);
 this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

优势 

组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JavaScript 中最常用的继承模式。 

劣势 

组合继承最大的问题就是无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。虽然子类型最终会包含超类型对象的全部实例属性,但我们不得不在调用子类型构造函数时重写这些属性。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用js实现键盘方向键翻页功能的代码
Jun 03 Javascript
我遇到的参数传递中 双引号单引号嵌套问题
Feb 11 Javascript
js改变img标签的src属性在IE下没反应的解决方法
Jul 23 Javascript
jQuery实现可收缩展开的级联菜单实例代码
Nov 27 Javascript
jQuery原型属性和原型方法详解
Jul 07 Javascript
Ionic实现页面下拉刷新(ion-refresher)功能代码
Jun 03 Javascript
Vue-router 类似Vuex实现组件化开发的示例
Sep 15 Javascript
解决vue 更改计算属性后select选中值不更改的问题
Mar 02 Javascript
javascript实现文本框标签验证的实例代码
Oct 14 Javascript
Vue学习之组件用法实例详解
Jan 06 Javascript
解决vuex刷新数据消失问题
Nov 12 Javascript
vue实现倒计时功能
Mar 24 Vue.js
Node.js读写文件之批量替换图片的实现方法
Sep 07 #Javascript
jQuery实现底部浮动窗口效果
Sep 07 #Javascript
聊一聊Vue.js过渡效果
Sep 07 #Javascript
BootStrap中的表单大全
Sep 07 #Javascript
JS实现title标题栏文字不间断滚动显示效果
Sep 07 #Javascript
JavaScript 函数模式详解及示例
Sep 07 #Javascript
jquery 属性选择器(匹配具有指定属性的元素)
Sep 06 #Javascript
You might like
php图像处理函数大全(推荐收藏)
2013/07/11 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
PHP判断FORM表单或URL参数来的数据是否为整数的方法
2016/03/25 PHP
php基于Redis消息队列实现的消息推送的方法
2018/11/28 PHP
网页设计常用的一些技巧
2006/12/22 Javascript
this[] 指的是什么内容 讨论
2007/03/24 Javascript
js中将URL中的参数提取出来作为对象的实现代码
2011/08/16 Javascript
javascript学习笔记(十三) js闭包介绍(转)
2012/06/20 Javascript
javascript设计模式 封装和信息隐藏(上)
2012/07/24 Javascript
基于JavaScript 声明全局变量的三种方式详解
2013/05/07 Javascript
ScrollDown的基本操作示例
2013/06/09 Javascript
js 表单提交后按钮变灰的实例代码
2013/08/16 Javascript
jQuery中[attribute=value]选择器用法实例
2014/12/31 Javascript
JavaScript DOM操作表格及样式
2015/04/13 Javascript
深入解读JavaScript中的Hoisting机制
2015/08/12 Javascript
javascript实现五星评分功能
2015/11/10 Javascript
解决JS无法调用Controller问题的方法
2015/12/31 Javascript
微信小程序 常用工具类详解及实例
2017/02/15 Javascript
JavaScript对象引用与赋值实例详解
2017/03/15 Javascript
canvas实现弧形可拖动进度条效果
2017/05/11 Javascript
vue实现商城上货组件简易版
2017/11/27 Javascript
ES6与CommonJS中的模块处理的区别
2018/06/13 Javascript
详解JavaScript的变量
2019/04/04 Javascript
JS中间件设计模式的深入探讨与实例分析
2020/04/11 Javascript
[51:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
python端口扫描系统实现方法
2014/11/19 Python
Python continue继续循环用法总结
2018/06/10 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
Python从ZabbixAPI获取信息及实现Zabbix-API 监控的方法
2018/09/17 Python
canvas绘制视频封面的方法
2018/02/05 HTML / CSS
会计专业毕业生求职信分享
2014/01/03 职场文书
面试自我介绍演讲稿
2014/04/29 职场文书
城管年度个人总结
2015/02/28 职场文书
农村婚庆主持词
2015/06/29 职场文书
认识实习感想
2015/08/10 职场文书
SQL Server2019数据库备份与还原脚本,数据库可批量备份
2021/11/20 SQL Server