用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 相关文章推荐
firefox下对ajax的onreadystatechange的支持情况分析
Dec 14 Javascript
js实现杯子倒水问题自动求解程序
Mar 25 Javascript
JS添加删除一组文本框并对输入信息加以验证判断其正确性
Apr 11 Javascript
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
May 07 Javascript
使用jQuery操作HTML的table表格的实例解析
Mar 13 Javascript
JavaScript SHA1加密算法实现详细代码
Oct 06 Javascript
纯JS实现轮播图
Feb 22 Javascript
详解处理bootstrap4不支持远程静态框问题
Jul 20 Javascript
vue中多路由表头吸顶实现的几种布局方式
Apr 12 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
Sep 11 Javascript
探索node之事件循环的实现
Oct 30 Javascript
Vue.js中v-for指令的用法介绍
Mar 13 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
简单易用的计数器(数据库)
2006/10/09 PHP
php数组函数序列之array_push() 数组尾部添加一个或多个元素(入栈),返回新长度。
2011/11/07 PHP
PHP常用特殊运算符号和函数总结(php新手入门必看)
2013/02/02 PHP
PHP实现生成唯一编号(36进制的不重复编号)
2014/07/01 PHP
PHP计算加权平均数的方法
2015/07/16 PHP
php中分页及SqlHelper类用法实例
2017/01/12 PHP
Laravel5.3+框架定义API路径取消CSRF保护方法详解
2020/04/06 PHP
thinkphp5.1 框架导入/导出excel文件操作示例
2020/05/25 PHP
IE8 引入跨站数据获取功能说明
2008/07/22 Javascript
javascript 操作select下拉列表框的一点小经验
2010/03/20 Javascript
jquery下异步提交表单 异步跨域提交表单
2010/11/17 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
2016/10/05 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
js实现select下拉框选择
2020/01/11 Javascript
vue-socket.io跨域问题有效解决方法
2020/02/11 Javascript
vue项目中自定义video视频控制条的实现代码
2020/04/26 Javascript
在Django的模型中执行原始SQL查询的方法
2015/07/21 Python
Python中的单行、多行、中文注释方法
2018/07/19 Python
python实现自动化上线脚本的示例
2019/07/01 Python
利用python下载scihub成文献为PDF操作
2020/07/09 Python
python中使用asyncio实现异步IO实例分析
2021/02/26 Python
DJI大疆无人机官方商城:全球领先的无人飞行器研发和生产商
2016/12/21 全球购物
Skyscanner台湾:全球知名的旅行比价引擎
2018/07/01 全球购物
应届生个人求职信模板
2013/11/26 职场文书
师恩难忘教学反思
2014/04/27 职场文书
爱之链教学反思
2014/04/30 职场文书
应届大专生自荐书
2014/06/16 职场文书
欢迎领导标语
2014/06/27 职场文书
2015年农村党员干部主题教育活动总结
2015/03/25 职场文书
银行岗位培训心得体会
2016/01/09 职场文书
领导激励员工的演讲稿,各种会上用得到,建议收藏
2019/08/13 职场文书
导游词之台湾安平古堡
2019/12/25 职场文书
Python预测分词的实现
2021/06/18 Python
nodejs利用readline提示输入内容实例代码
2021/07/15 NodeJs