用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 相关文章推荐
提高网站信任度的技巧
Oct 17 Javascript
js自动闭合html标签(自动补全html标记)
Oct 04 Javascript
JavaScript实现关键字高亮功能
Nov 12 Javascript
jQuery中last()方法用法实例
Jan 06 Javascript
JS实现模拟风力的雪花飘落效果
May 13 Javascript
Vue数据驱动模拟实现1
Jan 11 Javascript
Angular.js实现获取验证码倒计时60秒按钮的简单方法
Oct 18 Javascript
AngularJS集合数据遍历显示的实例
Dec 27 Javascript
jQuery代码优化方法总结
Jan 29 jQuery
vue实现点击按钮下载文件功能
Oct 11 Javascript
vue页面切换项目实现转场动画的方法
Nov 12 Javascript
Vue项目中如何封装axios(统一管理http请求)
May 02 Vue.js
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 遍历文件实现代码
2011/05/04 PHP
PHP遍历数组的几种方法
2012/03/22 PHP
php计划任务之ignore_user_abort函数实现方法
2015/01/08 PHP
php实现通过stomp协议连接ActiveMQ操作示例
2020/02/23 PHP
用jquery实现下拉菜单效果的代码
2010/07/25 Javascript
jQuery插件实现表格隔行换色且感应鼠标高亮行变色
2013/09/22 Javascript
jQuery中position()方法用法实例
2015/01/16 Javascript
js实现图片轮播效果
2015/12/19 Javascript
js删除局部变量的实现方法
2016/06/25 Javascript
ES6新特性之字符串的扩展实例分析
2017/04/01 Javascript
详解vue2路由vue-router配置(懒加载)
2017/04/08 Javascript
JS实现新建文件夹功能
2017/06/17 Javascript
JavaScript实现简单图片轮播效果
2017/08/21 Javascript
详解Vue 事件修饰符capture 的使用
2017/12/29 Javascript
Vue数据双向绑定的深入探究
2018/11/27 Javascript
layui的面包屑或者表单不显示的解决方法
2019/09/05 Javascript
微信小程序定义和调用全局变量globalData的实现
2019/11/01 Javascript
[51:39]DOTA2-DPC中国联赛 正赛 Magma vs LBZS BO3 第二场 2月7日
2021/03/11 DOTA
Anaconda下配置python+opencv+contribx的实例讲解
2018/08/06 Python
python pandas cumsum求累计次数的用法
2019/07/29 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
2019/12/13 Python
Python selenium自动化测试模型图解
2020/04/15 Python
Django如何实现密码错误报错提醒
2020/09/04 Python
html5教程制作简单画板代码分享
2013/12/04 HTML / CSS
VSCode 自定义html5模板的实现
2019/12/05 HTML / CSS
荷兰皇家航空公司中国官网:KLM中国
2017/12/13 全球购物
请问如下代码执行后a和b的值分别是什么
2016/05/05 面试题
请编写一个 C 函数,该函数在给定的内存区域搜索给定的字符,并返回该字符所在位置索引值
2014/09/15 面试题
岳父生日宴会答谢词
2014/01/13 职场文书
临床医师个人自我评价
2014/04/06 职场文书
故宫英文导游词
2015/01/31 职场文书
财务会计求职信范文
2015/03/20 职场文书
小学教育见习总结
2015/06/23 职场文书
大学毕业典礼致辞
2015/07/29 职场文书
会计岗位工作总结
2015/08/12 职场文书
2016年七夕情人节宣传语
2015/11/25 职场文书