JS学习专辑(7)-"类"的创建和继承

其实在JS中是没有类这个概念的,它没有像Class那样的专门定义的类,但我们一般可以通过对对象创建的模拟把它模拟成类。

书上介绍了几种创建类的方式,在这里:

1.工厂方式:这个方式在函数内部定义对象,并定义各种属性,最后返回对象。一般如果用这个的话我们把属性方法定义在函数外面,这样就可以避免重复创建该方法。

function Student1(name,age){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.f=f;
    
    return obj;
}
var f=function(){
    return (this.name+" "+this.age);
}
var student1=Student1("jk","12");
console.log(student1.name+" "+student1.age+" "+student1.f());    //jk 12 jk 12
if(student1 instanceof Student1){console.log("Y")}else{console.log("N")}    //N
View Code

只是上面这种方式无法进行对对象的类型的识别的,也就是说无法通过instanceof方法判断它属于那个类。

2.构造函数方式:这个方式使用构造函数创建对象,不用在函数内部创建,而使用this指代,不用return。同上一样,如果用这个就要把方法定义在外面。

function Student2(name,age){
    this.name=name;
    this.age=age;
    this.f=f;
}
var f=function(){
    return (this.name+" "+this.age);
}
var student2=new Student2("jk","12");
console.log(student2.name+" "+student2.age+" "+student2.f());    //jk 12 jk 12
if(student2 instanceof Student2){console.log("Y")}else{console.log("N")}    //Y
View Code

3.原型方式:在函数中不对属性进行定义,然后利用prototype的属性进行属性定义。

function Student3(name,age){
    
}
Student3.prototype={
    name:null,
    age:null,
    f:function(){
        return this.name+" "+this.age;
    }
};
var student3=new Student3;
student3.name="jk";
student3.age="12";
console.log(student3.name+" "+student3.age+" "+student3.f());    //jk 12 jk 12
View Code

只是单单用原型方式的话不是很好,因为当这个类有一个引用属性时,改变一个对象的这个属性也会改变其他对象得属性。比如一个Array再push进去东西的话,其他的对象属性也会更改。

4.混合的构造函数和原型模式(都推荐使用的是这个):将所有的不是方法的属性定义在函数中,将所有方法属性利用prototype定义在函数外面:

function Student4(name,age){
    this.name=name;
    this.age=age;
}
Student4.prototype.f=function(){
    return this.name+" "+this.age;
}
var student4=new Student4("jk",12);
console.log(student4.name+" "+student4.age+" "+student4.f());    ////jk 12 jk 12
View Code

这个是使用率最高的一种方式,也没有上面那些缺点。

5.动态原型方式(这个也是常用的):这个和上面那个是差不多的,都是在不是方法的属性定义在函数中,所有方法利用prototype定义。唯一的区别是赋予对象方法的位置。

function Student5(name,age){
    this.name=name;
    this.age=age;
    if(typeof Student5.f=="undefined"){
        Student5.prototype.f=function(){
            return this.name+" "+this.age;
        }
        Student5.f=true;
    }
}

var student5=new Student5("jk",12);
console.log(student5.name+" "+student5.age+" "+student5.f());    //jk 12 jk 12
View Code

上面一些就是类的创建的方法,然后类的继承的话最简单的是通过利用共享prototype实现继承,先看下例子:

function Student6(name,age){
    this.name=name;
    this.age=age;
}
Student6.prototype.f1=function(){
    return this.name;
}
Student6.prototype.f2=function(){
    return this.age;
}
function Candle(name,age,islight){
    this.name=name;
    this.age=age;
    this.islight=islight;
}
Candle.prototype=Student6.prototype;    //也可以这样Candle.prototype=new Student6();
Candle.prototype.f3=function(){
    return this.islight;
}
var student6=new Student6("jk",12);
console.log(student6.f1()+" "+student6.f2());    //jk 12
var candle=new Candle("jk",12,"no");
console.log(candle.f1()+" "+candle.f2()+" "+candle.f3());    //jk 12 no
console.log(candle instanceof Student6);    //true
console.log(candle instanceof Candle);        //true
View Code

上面的例子中第二个类继承了第一个类的f1和f2的方法,这是通过拷贝第一个类的prototype到第二个来实现的。然后用instanceof来判断了下对象是否是这两个类的实例是OK的。因为这个是用共享prototype的方法来实现定义的,是对同一个对象的引用,所以惟一的约束是不允许类成员的覆盖定义。

上面那种方法在不要求严格的情况下,这样的继承是比较简单方便的。但是毕竟如果成员的重新定义都会互相有影响,所以还有一种方法是通过反射机制和prototype实现继承,思路和上面那个差不多,但利用for(…in…)语句枚举出所有基类prototype的成员,并将其赋值给子类的prototype对象。下面是例子:

function Student7(name,age){
    this.name=name;
    this.age=age;
}
Student7.prototype.f1=function(){
    return this.name;
}
Student7.prototype.f2=function(){
    return this.age;
}
function Candle(name,age,islight){
    this.name=name;
    this.age=age;
    this.islight=islight;
}
//让Candle继承于Student7
for(var p in Student7){
    Candle.prototype[p]=Student7.prototype[p];
}
Candle.prototype.f1=function(){        //覆盖第一个类的f1方法
    return this.age;    
}
Candle.prototype.f2=function(){        //覆盖第一个类的f2方法
    return this.name;
}
Candle.prototype.f3=function(){
    return this.islight;
}
var student7=new Student7("jk",12);
console.log(student7.f1()+" "+student7.f2());    //jk 12
var candle=new Candle("jk",12,"no");
console.log(candle.f1()+" "+candle.f2()+" "+candle.f3());    //12 jk no
View Code

OK,上面的那些就是关于js类的创建和继承,如有新东西可以继续补充~

 

posted @ 2013-05-25 00:25  世界很灰暗  阅读(219)  评论(0编辑  收藏  举报