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

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组件。

(0)

相关推荐

  • JS继承--原型链继承和类式继承

    什么是继承啊?答:别人白给你的过程就叫继承. 为什么要用继承呢?答:捡现成的呗. 好吧,既然大家都想捡现成的,那就要学会怎么继承! 在了解之前,你需要先了解构造函数.对象.原型链等概念...... JS里常用的两种继承方式: 原型链继承(对象间的继承)类式继承(构造函数间的继承) 原型链继承: 复制代码 代码如下: //要继承的对象var parent={name : "baba" say : function(){ alert("I am baba");}} //

  • 实现JavaScript中继承的三种方式

    一.原型链继承 在原型链继承方面,JavaScript与java.c#等语言类似,仅允许单父类继承.prototype继承的基本方式如下: 复制代码 代码如下: function Parent(){} function Child(){} Child.prototype = new Parent(); 通过对象Child的prototype属性指向父对象Parent的实例,使Child对象实例能通过原型链访问到父对象构造所定义的属性.方法等. 构造通过原型链链接了父级对象,是否就意味着完成了对象

  • js的2种继承方式详解

    js中继承可以分为两种:对象冒充和原型链方式 一.对象冒充包括三种:临时属性方式.call()及apply()方式1.临时属性方式 复制代码 代码如下: function Person(name){     this.name = name;     this.say = function(){          alert('My name is '+this.name);     }}function F2E(name,id){     this.temp = Person;     thi

  • Prototype使用指南之base.js

    base.js中包含下面的内容  类的创建与继承: Class.create(): 创建一个类,例如 person=Class.create() Object.extend(destination, source): 把source中方法属性copy到destination(使用for propertyin source),需要注意的是,javascript中除了基本类型(Number, Boolean)外都是引用类型,所以这种copy一般只是copy引用而已,destination和sourc

  • Extjs学习笔记之八 继承和事件基础

    这里接口的意思是Observable实际上起了一个抽象类的作用,Extjs中有大量的组件都是继承自这个类的.这个类提供了一些基本的方法比如addEvents,addlistener,fireEvent等等. 本文暂时不介绍如何使用extjs的组件响应事件,而是介绍Extjs的事件的一些实现原理.整个Extjs框架都是以一种面向对象的方式开发的,所以理解Javascript中的继承也很重要.我前面的一篇文章 补点基础:Javascript中的类和闭包 也是为这篇做准备.另外,博客园内还有一个写的很

  • 深入理解JavaScript是如何实现继承的

    最近最网上看了一个人面试淘宝时的经历,然后发现了自己有好多好多不太清楚的地方,所以特此写点文章来加深自己对一些问题的理解. 文章中提到了一个问题是:JavaScript是如何实现继承的? 下面我便阐述一些在网上找到的方法和实例来解释下,借以加深自己的印象. 我们知道JavaScript中的function是万能的,除了用于的函数定义,也可以用于类的定义. JavaScript的继承,说起来也是有点怪,不像C++和一些面向对象的语言,他没有public,private等访问控制修饰,也没有impl

  • javascript的函数、创建对象、封装、属性和方法、继承

    一,function 从一开始接触到js就感觉好灵活,每个人的写法都不一样,比如一个function就有N种写法 如:function showMsg(){},var showMsg=function(){},showMsg=function(){} 似乎没有什么区别,都是一样的嘛,真的是一样的吗,大家看看下面的例子 复制代码 代码如下: ///----------------------------------------------------------------------------

  • JS仿Base.js实现的继承示例

    本文实例讲述了JS仿Base.js实现的继承.分享给大家供大家参考,具体如下: var Klass = function() {}; Klass.extendClass = (function() { var F = function() {}; return function(C, P) { F.prototype = P.prototype; C.prototype = new F(); C.uper = P.prototype; C.prototype.constructor = C; }

  • js实现继承的5种方式

    本文实例讲述了js实现继承的5种方式.分享给大家供大家参考,具体如下: 1.继承第一种方式:对象冒充 function Parent(username){ this.username = username; this.hello = function(){ alert(this.username); } } function Child(username,password){ //通过以下3行实现将Parent的属性和方法追加到Child中,从而实现继承 //第一步:this.method是作为

  • JavaScript是如何实现继承的(六种方式)

    前言:大多OO语言都支持两种继承方式: 接口继承和实现继承 ,而ECMAScript中无法实现接口继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠 原型链 来实现. 1.原型链 基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法. 构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针. 原型链实现继承例子: function SuperType() { this.property

  • 前端开发必须知道的JS之原型和继承

    一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称原型.这个函数包括构造函数和普通函数,我们讲的更多是构造函数的原型,但是也不能否定普通函数也有原型.譬如普通函数: 复制代码 代码如下: function F(){ alert(F.prototype instanceof Object) //true; } 构造函数,也即构造对象.首先了解下通过构造函数实例化对象的过程. 复制代码 代码如下: function A(x){ this.x

  • Javascript 继承机制的实现

    选定基类后,就可以创建它的子类了.是否使用基类完全由你决定.有时,你可能想创建一个不能直接使用的基类,它只是用于给子类提供通用的函数.在这种情况下,基类被看作抽象类. 尽管ECMAScript并没有像其他语言那样严格地定义抽象类,但有时它的确会创建一些不允许使用的类.通常,我们称这种类为抽象类. 创建的子类将继承超类的所有属性和方法,包括构造函数及方法的实现.记住,所有属性和方法都是公用的,因此子类可直接访问这些方法.子类还可添加超类中没有的新属性和方法,也可以覆盖超类中的属性和方法. 4.2.

  • js中继承的几种用法总结(apply,call,prototype)

    一,js中对象继承 js中有三种继承方式 1.js原型(prototype)实现继承 复制代码 代码如下: <SPAN style="BACKGROUND-COLOR: #ffffff"><SPAN style="FONT-SIZE: 18px"><html>  <body>  <script type="text/javascript">      function Person(na

随机推荐