用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 对象与DOM对象之两者相互间的转换
Apr 27 Javascript
让GoogleCode的SVN下的HTML文件在FireFox下正常显示.
May 25 Javascript
jQuery新闻滚动插件 jquery.roller.js
Jun 27 Javascript
这些年、我收集的JQuery代码小结
Aug 01 Javascript
jquery数组过滤筛选方法grep()简介
Jun 06 Javascript
JavaScript正则表达式的分组匹配详解
Feb 13 Javascript
JS异步函数队列功能实例分析
Nov 28 Javascript
一次记住JavaScript的6个正则表达式方法
Feb 22 Javascript
JS实现左边列表移到到右边列表功能
Mar 28 Javascript
利用vue重构有赞商城的思路以及总结整理
Feb 21 Javascript
vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多(步骤详解)
Jan 14 Javascript
微信小程序vant弹窗组件的实现方式
Feb 21 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
PHP 采集获取指定网址的内容
2010/01/05 PHP
thinkPHP自动验证、自动添加及表单错误问题分析
2016/10/17 PHP
基于JQuery的类似新浪微博展示信息效果的代码
2012/07/23 Javascript
jquery数组之存放checkbox全选值示例代码
2013/12/20 Javascript
js实现文本框中焦点在最后位置
2014/03/04 Javascript
再谈Jquery Ajax方法传递到action(补充)
2014/05/12 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
javascript实现完美拖拽效果
2015/05/06 Javascript
js实现select二级联动下拉菜单
2020/04/17 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
2016/12/13 Javascript
JavaScript中动态向表格添加数据
2017/01/24 Javascript
关于react-router的几种配置方式详解
2017/07/24 Javascript
使用pm2部署node生产环境的方法步骤
2019/03/09 Javascript
浅谈webpack 四个核心概念之Entry
2019/06/12 Javascript
javascript中的with语句学习笔记及用法
2020/02/17 Javascript
vuex实现购物车功能
2020/06/28 Javascript
vue使用video插件vue-video-player的示例
2020/10/03 Javascript
python获取局域网占带宽最大3个ip的方法
2015/07/09 Python
Python实现的生成格雷码功能示例
2018/01/24 Python
Python实现按当前日期(年、月、日)创建多级目录的方法
2018/04/26 Python
详解从Django Rest Framework响应中删除空字段
2019/01/11 Python
分享PyCharm的几个使用技巧
2019/11/10 Python
Python中的引用和拷贝实例解析
2019/11/14 Python
django模板获取list中指定索引的值方式
2020/05/14 Python
利用python+ffmpeg合并B站视频及格式转换的实例代码
2020/11/24 Python
Numpy中np.max的用法及np.maximum区别
2020/11/27 Python
Java中采用什么结构来捕获、处理异常?各子句的顺序、功能如何
2013/10/07 面试题
记者岗位职责
2014/01/06 职场文书
行政专员岗位职责范本
2014/08/26 职场文书
个人授权委托书样本
2014/09/13 职场文书
执法作风整顿剖析材料
2014/10/11 职场文书
临时工聘用合同协议书
2014/10/29 职场文书
优秀党员先进材料
2014/12/18 职场文书
2016年公司新年寄语
2015/08/17 职场文书
最新农村养殖致富:资金投入较低的创业项目有哪些?
2019/09/26 职场文书
Spring Bean是如何初始化的详解
2022/03/22 Java/Android