JavaScript实现继承

继承

继承的方式有两种,一种是接口继承,继承方法签名,一种是实现继承,继承实际的方法。JavaScript由于没有方法签名,所以只支持实现继承

原型链

JavaScript实现继承的方式是用原型链来实现的。由于每个构造函数都一个属性,指向一个原型对象,所以我们将原型对象等于另一个类型的实例,显然这时这个实例中有一个指向另一个原型的指针。如果这样一层一层的嵌套下去,就构成一个原型链。

    function Super(){
        this.property=true;
    }
    Super.prototype.getSuperValue=function(){
        return this.property;
    }   
    function Sub{
        this.subProperty=false;
    }
    //Sub 继承 Super
    Sub.prototype=new Super();
    Sub.prototype.getSubValue(){
        return this.subProperty;
    }
    var instance=new Sub();
    alert(instance.getSuperValue());  //true

实现了继承之后,原型搜索机制会改变。当搜索一个实例属性时,会分为以下几部:
1)在实例中搜索
2)在Sub.prototype中搜索
3)在Super.prototype中搜索

确定原型和实例的关系

有两种方法来确定原型和实例之间的关系。第一种:使用instanceof操作符来测试实例与原型链中出现过的构造函数。

    alter(instance instanceof Object);//true
    alter(instance instanceof Super);//true
    alter(instance instanceof Sub);//true

使用isPrototypeOf()方法。

    alter(Object.prototype.isPrototypeOf(instance));//true
    alter(Super.prototype.isPrototypeOf(instance));//true
    alter(Sub.prototype.isPrototypeOf(instance));//true

实现继承需要注意一下几点:
1)instance的constructor指向的是Super。因为Sub指向了Super的实例,指向了Super的原型,而这个原型对象的constructor指向的是Super。
2)通过原型联 实现继承时,不能使用对象字面量创建原型方法,因为这样就重写原型链。

原型链的问题:包含引用类型的属性。若Super中含有引用类型的实例属性,则Sub类型的所有实例引用的都是同一个实例属性,若对其中一个值进行改变,则其他Sub实例的值也会改变。同时,在创建子类类型时,不能像父类构造函数中传值。

借用构造函数

    function Super(){
        this.colors=["red","blue","green"];
    }

    function Sub{
        //继承Super
        Super.call(this);
    }

    var instance1=new Sub();
    instance1.colors.push("black");
    alert(instance1.colors);  //red,blue,green,balck
    var instance2=new Sub();
    alert(instance2.colors);  //red,blue,green

通过call方法,我们在Sub的执行环境下调用了Super的构造函数,使得每个Sub实例都有一个属于自己的colors。而且使用call方法还可以像父类构造函数传参。

组合继承

组合继承是指将原型链和借用构造函数的技术组合到一起。使用原型链来实习对方法和共享属性的继承,使用借用函数来实现对实例属性的继承。
组合继承是JavaScript中最常用的继承模式。

你可能感兴趣的:(javascript)