用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 相关文章推荐
js 固定悬浮效果实现思路代码
Aug 02 Javascript
使用简洁的jQuery方法实现隔行换色功能
Jan 02 Javascript
实现图片预加载的三大方法及优缺点分析
Nov 19 Javascript
jQuery构造函数init参数分析
May 13 Javascript
Javascript页面跳转常见实现方式汇总
Nov 28 Javascript
JS判断一个数是否是水仙花数
Jun 11 Javascript
Vue 2.0在IE11中打开项目页面空白的问题解决
Jul 16 Javascript
vue jsx 使用指南及vue.js 使用jsx语法的方法
Nov 11 Javascript
原生JS实现$.param() 函数的方法
Aug 10 Javascript
泛谈JS逻辑判断选择器 || &amp;&amp;
May 24 Javascript
JavaScript实现轮播图效果
Oct 30 Javascript
比较node.js和Deno
Apr 27 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
DC动漫人物排行
2020/03/03 欧美动漫
六酷社区论坛HOME页清新格调免费版 下载
2007/03/07 PHP
php教程 插件机制在PHP中实现方案
2012/11/02 PHP
thinkphp 一个页面使用2次分页的实现方法
2013/07/15 PHP
zen_cart实现支付前生成订单的方法
2016/05/06 PHP
PHP使Laravel为JSON REST API返回自定义错误的问题
2018/10/16 PHP
JS 用6N±1法求素数 实例教程
2009/10/20 Javascript
jquery教程ajax请求json数据示例
2014/01/13 Javascript
Jquery实现点击按钮,连续地向textarea中添加值的实例代码
2014/03/08 Javascript
基于jquery的手风琴图片展示效果实现方法
2014/12/16 Javascript
jQuery unbind()方法实例详解
2016/01/19 Javascript
AngularJS整合Springmvc、Spring、Mybatis搭建开发环境
2016/02/25 Javascript
Jquery实现的简单轮播效果【附实例】
2016/04/19 Javascript
浅谈在js传递参数中含加号(+)的处理方式
2016/10/11 Javascript
jquery利用json实现页面之间传值的实例解析
2016/12/12 Javascript
详解React native全局变量的使用(跨组件的通信)
2017/09/07 Javascript
JavaScript对象拷贝与Object.assign用法实例分析
2018/06/20 Javascript
新手如何快速理解js异步编程
2019/06/24 Javascript
原生js+ajax分页组件
2020/01/30 Javascript
element 中 el-menu 组件的无限极循环思路代码详解
2020/04/26 Javascript
手把手带你搭建一个node cli的方法示例
2020/08/07 Javascript
Python实现类似jQuery使用中的链式调用的示例
2016/06/16 Python
Python实现带百分比的进度条
2016/06/28 Python
深入浅析Python中的yield关键字
2018/01/24 Python
Python实现简单http服务器
2018/04/12 Python
python爬虫获取新浪新闻教学
2018/12/23 Python
np.random.seed() 的使用详解
2020/01/14 Python
HTML5 和小程序实现拍照图片旋转、压缩和上传功能
2018/10/08 HTML / CSS
html5绘制时钟动画
2014/12/15 HTML / CSS
6号汽车旅馆预订:Motel 6
2018/02/11 全球购物
Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
2015/01/27 面试题
办公室文秘自我鉴定
2013/09/21 职场文书
校园十佳歌手策划书
2014/01/22 职场文书
党员一帮一活动总结
2014/07/08 职场文书
出纳试用期工作总结2015
2015/05/28 职场文书
PHP中多字节字符串操作实例详解
2021/08/23 PHP