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 相关文章推荐
最简单的JavaScript验证整数、小数、实数、有效位小数正则表达式
Apr 17 Javascript
AngularJS内建服务$location及其功能详解
Jul 01 Javascript
深入浅析javascript中的作用域(推荐)
Jul 19 Javascript
BootStrapTable 单选及取值的实现方法
Jan 10 Javascript
如何获取元素的最终background-color
Feb 06 Javascript
ztree实现权限横向显示功能
May 20 Javascript
vuex与组件联合使用的方法
May 10 Javascript
Vue中使用的EventBus有生命周期
Jul 12 Javascript
实例详解BootStrap的动态模态框及静态模态框
Aug 13 Javascript
vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法
Sep 19 Javascript
微信小程序实现签到功能
Oct 31 Javascript
vue-router传参用法详解
Jan 19 Javascript
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
雄兵连三大错觉:凯莎没了,凉冰阵亡了,华烨觉得自己又行了
2020/04/09 国漫
PHP扩展模块Pecl、Pear以及Perl的区别
2014/04/09 PHP
PHP中使用break跳出多重循环代码实例
2015/01/21 PHP
PHP的命令行命令使用指南
2015/08/18 PHP
PHP设计模式之迭代器模式
2016/06/17 PHP
php通过两层过滤获取留言内容的方法
2016/07/11 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
2018/06/16 PHP
Yii2框架配置文件(Application属性)与调试技巧实例分析
2019/05/27 PHP
javascript学习笔记(一) 在html中使用javascript
2012/06/18 Javascript
js 弹出框只弹一次(二次修改之后的)
2013/11/26 Javascript
nodejs下打包模块archiver详解
2014/12/03 NodeJs
Javascript实现鼠标右键特色菜单
2015/08/04 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
浅析JS异步加载进度条
2016/05/05 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
js使用highlight.js高亮你的代码
2017/08/18 Javascript
JavaScript Canvas编写炫彩的网页时钟
2019/10/16 Javascript
electron+vue实现div contenteditable截图功能
2020/01/07 Javascript
基于js实现判断浏览器类型代码实例
2020/07/17 Javascript
antd design table更改某行数据的样式操作
2020/10/31 Javascript
javascript实现搜索筛选功能实例代码
2020/11/12 Javascript
[01:06:25]Secret vs Liquid 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
Python PyQt5标准对话框用法示例
2017/08/23 Python
python修改txt文件中的某一项方法
2018/12/29 Python
完美解决python3.7 pip升级 拒绝访问问题
2019/07/12 Python
利用Python中的Xpath实现一个在线汇率转换器
2020/09/09 Python
python接口自动化框架实战
2020/12/23 Python
基于Pytorch版yolov5的滑块验证码破解思路详解
2021/02/25 Python
欧洲领先的火车票和大巴票预订平台:Trainline
2018/12/26 全球购物
Allen Edmonds官方网站:一家美国优质男士鞋类及配饰制造商
2019/03/12 全球购物
德国在线购买葡萄酒网站:Geile Weine
2019/09/24 全球购物
墨西哥购物网站:Elektra
2020/01/21 全球购物
英语系毕业生求职信
2014/07/13 职场文书
家长对孩子的寄语
2015/02/26 职场文书
2015选调生工作总结
2015/07/24 职场文书
python绘制简单直方图(质量分布图)的方法
2022/04/21 Python