JavaScript继承与聚合实例详解

第一种方式:类与被继承类直接耦合度高

1. 首先,准备一个可以被继承的类(父类),例如

//创建一个人员类 function Person(name) {//现在Person里面的域是由Person里面的 来this来控制的 this.name=name; }

2. 然后,有个需要继承父类的子类

function Teacher(name,books) { Person.call(this,name);//相当于java中的super函数 在new Teacher时将Person的name初始化 this.books=books; }

说明一下:

(1)call方法可以将一个函数的对象上下文从初始化变成由this来决定一个类去控制另一个类

(2)Teacher类去控制 Person类 用Teacher域里面的 this来控制Person域里面的 this

(3)调用 Perosn的构造函数,因为Perosn没有用 new 所以是个空对象(模板)     显示调用call方法,可以初始化 Person

3. 最后,实现继承

(步骤1)先继承

Teacher.prototype=new Person(); Teacher.prototype.constructor=Teacher;//确保继承后任然是Teacher自己的构造函数

(步骤2)为子类扩展一些方法,用于访问从父类继承的内容

Teacher.prototype.getBook=function () { return this.name+" "+this.books; }

(步骤3)使用已经继承好的类

var jim=new Teacher("Jim","Javascript"); alert(jim.getBook())

总结:此种方法是直接在子类中显示调用父类,耦合度高,复用性差。

第二种方式,使用封装,完成程序中所用继承操作

1. 首先,准备一个可以被继承的类(父类),例如

//创建一个人员类 function Person(name) {//现在Person里面的域由Person里面的来this来控制的 this.name=name; }

2. 创建extend函数为了程序中所有的继承操作(最重要的地方)

/*创建extend函数为了程序中所有的继承操作*/ //subClass:子类 superClass:超类(2) function extend(subClass,superClass) { //1,使子类原型属性等于父类的原型属性 //初始化一个中间空对象,目的是为了转换主父关系 var F = function () {}; F.prototype = superClass.prototype; //2, 让子类继承F subClass.prototype = new F(); subClass.prototype.constructor = subClass; //3,为子类增加属性 superClass ==》原型链的引用 subClass.superClass = superClass.prototype; //4,增加一个保险,就算你的原型类是超类(Object)那么也要把你的构造函数级别降下来 【说明一些:这里只是其中一个简单的保险,其余情况后续增加。。。】 if (superClass.prototype.constructor == Object.prototype.constructor) { superClass.prototype.constructor = superClass; } }

3. 有一个需要继承其他类的子类

function Author(name,books) { Author.superClass.constructor.call(this,name);//没有直接写父类,降低了耦合度 //Person.call(this,name) 直接写Person代表其构造函数 this.books=books; this.getBooks=function () { return this.name+" "+this.books ; } }

4. 最后,实现继承

//继承 extend(Author,Person);//(子类,父类)

5. 使用已经继承好的类

var peter=new Author("Peter","Javascript"); alert(peter.getBooks());

方式二图解为:

JavaScript继承与聚合实例详解

这里可能会有一个疑问就是为啥要使用中间类???

这里假如没有中间类的话,我们在实例化子类时就需要为父类传递一些相应的参数,这样的话,该句代码

Author.superClass.constructor.call(this,name);

就不能放在子类(Author)中,而是需要放入到extend中,这样的话代码的通用性就很低,故此需要使用中间类。

二、聚合

使用聚合的原因,有的时候不需要严格的继承,我们真正需要的是一个类(或几个类)中的一些函数。故此我们可以使用聚合 也就是使用 掺元类

对于聚合有两种情况

第一种是聚合到 var a={}空类或者不是用function声明的类中

1. 首先,需要一个合适的可以被聚合的类(给体),此时需要在本类的内部进行扩展属性,方法

var JSON={//写到类的内部 toJsonString:function () { var output=[]; for(key in this){//this代表那个调用,就指向那个一个对象 output.push(key+"---->"+this[key]); } return output; } };

2. 制作一个聚合函数(最重要)

/*聚合函数 receivingClass:接受聚合内容的类 givingClass:被聚合的目标类 * */ function mixin(receivingClass,givingClass){ for(methodName in givingClass){ if(!receivingClass.__proto__[methodName]){//判断当前原型中是否含有即将要被聚合的方法,若没有则聚合进来 receivingClass.__proto__[methodName]=givingClass[methodName];//直接获得类中的方法,因为方法是直接写在方法内部的。 } } }


3. 接受聚合的类(受体)

var get={name:"Text",age:20};

4. 实现将JSON类的方法聚合到类get中

mixin(get,JSON);//(受体,给体)

5. 使用get类中聚合的方法

document.write(get.toJsonString().join(","));

第二种是聚合用function声明的类中

var a=function(){}

1. 首先,需要一个合适的可以被聚合的类(给体),此时需要在本类的原型对象上进行扩展属性,方法

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/ec538f1d7270aa42bb95575d4ab7ec07.html