JavaScript中的继承机制

JavaScript到底是不是面向对象的?!

有人说是,有人说基于对象更准确,因为JavaScript没有类。不去管它,但JavaScript确实提供了一些面向对象的机制。

本文主要讨论JavaScript中的继承。继承,简单来说,就是让子类获得父类的属性和方法,以达到共享和复用的目的。

在开始继承之前,首先需要创建父类。为了后续讨论的需要,我分别为父类创建了私有对象、实例对象、引用对象和两个实例方法。

创建父类的代码如下:

// 父类实例的构造函数
function Pet(name,sound){
    // 私有对象
    var name = "this is a pet";
    // 实例对象
    this.sound = "I'm a pet";
    // 引用对象
    this.loveFood = [];
    // 实例方法
    this.getName = function(){
        console.log(name);
    };
    this.getLoveFood = function(){
        for(var food in this.loveFood){
            console.log(this.loveFood[food]);
        }
    };
}
// 原型对象上的方法
Pet.prototype.voice = function(){
    console.log(this.sound);
}

接下来,我们来看在JavaScript中几种能完成继承的手段,他们分别是new方式、extend方式、clone方式和mixin方式。

(1)new方式

    // 子类构造函数
    function Dog(sound){
        if(sound){
            this.sound = sound;
        }
    }

    // 使子类构造函数的原型对象指向父类的一个实例
    Dog.prototype = new Pet;
    // 调整子类构造函数的原型对象的constructor指向
    Dog.prototype.constructor = Dog;

    var dog1 = new Dog("wangwang");
    console.log(dog1.sound);//wangwang
    dog1.getName();//this is a pet
    dog1.voice();//wangwang
    dog1.loveFood.push("pork");
    dog1.getLoveFood();//pork

    console.log("dog2");
    var dog2 = new Dog();
    dog2.voice();//I'm a pet
    dog2.getLoveFood();//pork

    console.log(dog1 instanceof Dog);//true
    console.log(dog1 instanceof Pet);//true

 

(2)extend方式

    function extend(b,p){
        var F= function(){};
        F.prototype = p.prototype;
        b.prototype = new F();
        b.prototype.constructor = b;
        b.su = p.prototype;
    }

    // 子类构造函数
    function Dog(sound){
        if(sound){
            this.sound = sound;
        }
    }
    extend(Dog,Pet);

    var dog1 = new Dog("wangwang");
    console.log(dog1.sound);
    // 报错
    // dog1.getName();
    dog1.voice();
    // 报错
    // dog1.loveFood.push("pork");
    dog1.getLoveFood();

    console.log("dog2");
    var dog2 = new Dog();
    // 报错
    // dog2.getName();
    dog2.voice();
    dog2.getLoveFood();    

(3)clone方式

    function clone(o){
        function F(){};
        F.prototype = o;
        return new F;
    }
    var Dog={
        name:"this is a dog",
        sound:"wangwang",
        loveFood:[],
        voice:function(){console.log(this.sound);},
        getLoveFood:function(){
            for(var food in this.loveFood){
                console.log(this.loveFood[food]);
            }
        }
    };
    var jwawa = clone(Dog);
    jwawa.voice();
    jwawa.name = "jjjj";
    jwawa.loveFood.push("meat");
    console.log("Dog.name = "+Dog.name);
    console.log("jwawa.name = "+jwawa.name);
    // meat
    jwawa.getLoveFood();
    var shapi = clone(Dog);    
    console.log("shapi.name = "+shapi.name);
    // meat
    shapi.getLoveFood();

(4)mixin方式

    var Mixin = function(){};
    Mixin.prototype ={
        serialize:function(){
            var output =[];
            for(key in this){
                output.push(key + ':' + this[key]);
            }
            return output.join(',');
        }
    };
    function augment(receivingClass,givingClass){
        if(arguments[2]){
            for (var i = arguments.length - 1; i >= 0; i--) {
                receivingClass.prototype[arguments[i]] = givingClass.prototype[arguments[i]];
            };
        }else{
            for(methodName in givingClass.prototype){
                if(!receivingClass.prototype[methodName]){
                    receivingClass.prototype[methodName] = givingClass.prototype[methodName];
                }
            }
        }
    }
    function Book(){
        this.name = "123";
        this.price = 456;
        this.year = "2015";
    }
    Book.prototype.show = function(){console.log("show");};
    augment(Book,Mixin);
    var book = new Book;
    console.log(book.serialize());
    // 输出
    // name:123,price:456,year:2015,show:function (){console.log("show");},serialize:function (){
    //         var output =[];
    //         for(key in this){
    //             output.push(key + ':' + this[key]);
    //         }
    //         return output.join(',');
    //     }
posted @ 2015-04-25 10:48  WFE-Hank  阅读(180)  评论(0编辑  收藏  举报