用JavaScript实现单继承和多继承的简单方法


Posted in Javascript onMarch 29, 2009

JavaScript就其本质是函数式编程语言,是Lisp的后代,同时又加入了一下面向对象编程的元素,放弃了一些难懂的函数式语言的元素。

函数式编程语言可以实现面向对象编程,这是毫无疑义的,Curry方法可以实现对类和对象的模拟。但是JavaScript提供了另一种实现OOP的方法:原型继承。

因此,JavaScript实现面向对象编程和一般的函数式编程语言还是有所区别的。

本文我将会给大家介绍JavaScript实现单继承和多继承的方法。

用原型实现单继承:
有很多JavaScript库提供了一些函数帮助实现单继承。但实际上,JavaScript本身就提供了原型继承的方法。因此,根本不需要提供特定的方法来实现,简单使用JavaScript代码就可以实现单继承。

但是,JavaScript提供的原型继承方法很容易犯错,下面我给大家演示一下怎样简洁明了地实现原型继承。

假设MyB继承MyA类,那么,代码如下:

function MyA(){

if(MyA.prototype.baseClass!==undefined){

MyA.prototype.baseClass.call(this);

}

……一般代码

}

function MyB(){

if(MyB.prototype.baseClass!==undefined){

MyB.prototype.baseClass.call(this);

}

……一般代码

}

MyB.prototype=new MyA();

MyB.prototype.baseClass=MyB.prototype.constructor;//使用baseClass引用//基类的构造器函数。

MyB.prototype.constructor=MyB;//恢复子类的构造器属性 用于未来通过这个属性判//断对象的类型。

var myA=new MyA();

var myB=new MyB();

上述javascript代码中,我在每一个构造函数中都添加了这么一段代码:

if(ClassName.prototype.baseClass!==undefined){

ClassName.prototype.baseClass.call(this);

}

这段代码寻找原型中的baseClass方法,如果有,就调用它。

在后面的原型继承的实现中,我为子类创建了baseClass属性,它的值是基类的构造函数。因此,只要遵守我的方式编写代码,就可以保证基类的构造函数在子类构造实例时会得到执行。

现在,如果MyA类又继承了Base类,只需要添加3行原型继承代码即可:

MyA.prototype=new Base();

MyA.prototype.baseClass= MyA.prototype.constructor;//使用baseClass引用//基类的构造器函数。

MyA.prototype.constructor= MyA;//恢复子类的构造器属性 用于未来通过这个属性判//断对象的类型。

不需要修改MyA类本身的代码,MyA类及其子类MyB类的实例就都可以得到正确的执行。

那些JavaScript库实现的继承,需要修改Object,Function等基类,容易引起冲突。还有一些方法,每一次实现继承,都必须手工修改子类的构造函数,以使构造函数能够正确调用基类的构造函数。

上面提供的方法编写JavaScript代码很好地解决了这些问题。

用Mixin(混入)实现多继承
JavaScript本身并没有提供多继承的机制,但我们可以使用Mixin(混入)这种技巧实现多继承的效果。

下面是我编写的Mixin助手方法,可以为类和对象动态添加属性。

1,copyClassPrototypeProperties复制类的原型属性
/**

* 把源类原型上的所有属性复制到目标对象上,第一个参数是boolean值,表示是否覆盖目标类的原型的属性

*/

function copyClassPrototypeProperties(isOverride,receivingClass,givingClass){

if(arguments.length>3){

for(var i=3;i<arguments.length;i++){

receivingClass.prototype[arguments[i]]=givingClass.prototype[arguments[i]];

}

}else if(arguments.length==3){

for(var name in givingClass.prototype){

if(isOverride){

receivingClass.prototype[name]=givingClass.prototype[name];

}else{

//不覆盖

if(!receivingClass.prototype[name]){

receivingClass.prototype[name]=givingClass.prototype[name];

}

}
}

}else{

throw "Please give 3 arguments at least!";

}
}

2,copyObjectProperties复制对象的属性
/*

* 把源对象的所有属性复制到目标对象上,第一个参数是boolean值,表示是否覆盖目标对象的属性

*/

function copyObjectProperties(isOverride,receivingObject,givingObject){

if(arguments.length>3){

for(var i=3;i<arguments.length;i++){

receivingObject[arguments[i]]=givingObject[arguments[i]];

}

}else if(arguments.length==3){

for(var name in givingObject){

if(isOverride){

receivingObject[name]=givingObject[name];

}else{

//不覆盖

if(!receivingObject[name]){

receivingObject[name]=givingObject[name];

}

}
}

}else{

throw "Please give 3 arguments at least!";
}
}

3,copyProperties复制属性到对象
/*

* 把属性复制到目标对象中,属性可以有任意多个,并且可以是数组。

*/

function copyProperties(target){

for (var i=1;i<arguments.length;i++){

if(arguments[i].constructor===Array){

copyArrayProperties(target,arguments[i]);

}else{

for(var name in arguments[i]){

target[name] =arguments[i][name];

}
}
}
}
/*

* 把数组格式的属性复制到目标对象中,用户不应该直接调用这个方法

*/

function copyArrayProperties(target,arrayArg){

for(var i=0;i<arrayArg.length;i++){
if(arrayArg[i].constructor===Array){
copyArrayProperties(target,arrayArg[i]);

}else{
for(var name in arrayArg[i]){
target[name] =arrayArg[i][name];
}
}
}
}
PS:目前我正打算写一个JavaScript库,用简洁的代码提供很多功能,包括UI组件。

Javascript 相关文章推荐
jQuery 淡入淡出 png图在ie8下有黑色边框的解决方法
Mar 05 Javascript
document.createElement()用法及注意事项(ff下不兼容)
Mar 13 Javascript
Jquery Ajax解析XML数据(同步及异步调用)简单实例
Feb 12 Javascript
JavaScript  event对象整理及详细介绍
Oct 10 Javascript
微信小程序 购物车简单实例
Oct 24 Javascript
详解在vue-cli项目中使用mockjs(请求数据删除数据)
Oct 23 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
Nov 10 Javascript
vue实现某元素吸顶或固定位置显示(监听滚动事件)
Dec 13 Javascript
vue组件实现弹出框点击显示隐藏效果
Oct 26 Javascript
深入理解Vue 组件之间传值
Aug 16 Javascript
其实你可以少写点if else与switch(推荐)
Jan 10 Javascript
原生JavaScript实现轮播图
Jan 10 Javascript
javascript 极速 隐藏/显示万行表格列只需 60毫秒
Mar 28 #Javascript
一个tab标签切换效果代码
Mar 27 #Javascript
js onpropertychange输入框 事件获取属性
Mar 26 #Javascript
input 高级限制级用法
Mar 26 #Javascript
HTML代码中标签的全部属性 中文注释说明
Mar 26 #Javascript
JS 常用校验函数
Mar 26 #Javascript
js 动态添加标签(新增一行,其实很简单,就是几个函数的应用)
Mar 26 #Javascript
You might like
收音机指标测试方法及仪器
2021/03/01 无线电
php邮件发送,php发送邮件的类
2011/03/24 PHP
Yii入门教程之Yii安装及hello world
2014/11/25 PHP
php文件上传 你真的掌握了吗
2016/11/28 PHP
使用IE6看老赵的博客 jQuery初探
2010/01/17 Javascript
将字符串转换成gb2312或者utf-8编码的参数(js版)
2013/04/10 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
2013/06/27 Javascript
alert和confirm功能介绍
2014/05/21 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
2016/01/17 Javascript
Bootstrap实现input控件失去焦点时验证
2016/08/04 Javascript
JavaScript中的await/async的作用和用法
2016/10/31 Javascript
vue绑定设置属性的多种方式(5)
2017/08/16 Javascript
微信小程序 checkbox使用实例解析
2019/09/09 Javascript
vue 设置 input 为不可以编辑的实现方法
2019/09/19 Javascript
vue登录以及权限验证相关的实现
2019/10/25 Javascript
24行JavaScript代码实现Redux的方法实例
2019/11/17 Javascript
[57:24]LGD vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python操作Mysql实例代码教程在线版(查询手册)
2013/02/18 Python
使用python Django做网页
2013/11/04 Python
Python的Tornado框架异步编程入门实例
2015/04/24 Python
对pandas replace函数的使用方法小结
2018/05/18 Python
基于Python实现扑克牌面试题
2019/12/11 Python
Python self用法详解
2020/11/28 Python
CSS超出文本指定宽度用省略号代替和文本不换行
2016/05/05 HTML / CSS
美国职棒大联盟的官方手套、球和头盔:Rawlings
2020/02/15 全球购物
沙特阿拉伯排名第一的在线时尚购物应用程序:1Zillion
2020/08/08 全球购物
PHP如何调用MYSQL存储过程
2014/05/30 面试题
如何现实servlet的单线程模式
2014/08/05 面试题
旅游管理本科生求职信
2013/10/14 职场文书
给医务人员表扬信
2014/01/12 职场文书
网络技术专业求职信
2014/02/18 职场文书
用人单位终止解除劳动合同证明书
2014/10/06 职场文书
检讨书怎么写?
2019/06/21 职场文书
创业计划书之婴幼儿游泳馆
2019/09/11 职场文书
python 详解turtle画爱心代码
2022/02/15 Python
Python可视化神器pyecharts之绘制箱形图
2022/07/07 Python