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 相关文章推荐
学习面向对象之面向对象的基本概念:对象和其他基本要素
Nov 30 Javascript
dreamweaver 安装Jquery智能提示
Apr 02 Javascript
详解强大的jQuery选择器之基本选择器、层次选择器
Feb 07 Javascript
js鼠标滑过弹出层的定位IE6bug解决办法
Dec 26 Javascript
转换字符串为json对象的方法详解
Nov 29 Javascript
JavaScript Math.round() 方法
Dec 18 Javascript
深入理解bootstrap框架之入门准备
Oct 09 Javascript
360doc网站不登录就无法复制内容的解决方法
Jan 27 Javascript
玩转vue的slot内容分发
Sep 22 Javascript
在Node.js下运用MQTT协议实现即时通讯及离线推送的方法
Jan 24 Javascript
vue中filters 传入两个参数 / 使用两个filters的实现方法
Jul 15 Javascript
Vue自定义铃声提示音组件的实现
Jan 22 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
oracle资料库函式库
2006/10/09 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
PHP登录(ajax提交数据和后台校验)实例分享
2016/12/29 PHP
javascript之解决IE下不渲染的bug
2007/06/29 Javascript
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
jQuery EasyUI API 中文文档 - Parser 解析器
2011/09/29 Javascript
jQuery当鼠标悬停时放大图片的效果实例
2013/07/03 Javascript
jQuery获得内容和属性方法及示例
2013/12/02 Javascript
JavaScript中的console.group()函数详细介绍
2014/12/29 Javascript
使用javascript实现json数据以csv格式下载
2015/01/09 Javascript
jQuery获取URL请求参数的方法
2015/07/18 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
2016/02/29 Javascript
JS 数字转换为大写金额的简单实例
2016/08/04 Javascript
jQuery实现的小图列表,大图展示效果幻灯片示例
2016/10/25 Javascript
js与jquery分别实现tab标签页功能的方法
2016/11/18 Javascript
基于js实现二级下拉联动
2016/12/17 Javascript
微信小程序实现文字跑马灯效果
2020/05/26 Javascript
Vue.js中 v-model 指令的修饰符详解
2018/12/03 Javascript
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
教你利用Python玩转histogram直方图的五种方法
2018/07/30 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
Python csv文件记录流程代码解析
2020/07/16 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
2020/08/31 Python
使用css3制作登录表单的步骤
2014/04/07 HTML / CSS
介绍一下游标
2012/01/10 面试题
常见的软件开发流程有哪些
2015/11/14 面试题
银行优秀员工事迹
2014/02/06 职场文书
企业党建工作汇报材料
2014/08/19 职场文书
海底两万里读书笔记
2015/06/26 职场文书
会计做账心得体会
2016/01/22 职场文书
关于感恩老师的古诗句
2019/08/20 职场文书
nginx+lua单机上万并发的实现
2021/05/31 Servers
详解nginx进程锁的实现
2021/06/14 Servers
Java数组与堆栈相关知识总结
2021/06/29 Java/Android
Win10加载疑难解答时出错发生意外错误的解决方法
2022/07/07 数码科技