首页 > 代码库 > JavaScript实现继承总结

JavaScript实现继承总结

原型链
function SuperType(){
    this.property="SuperType_true";
}

SuperType.prototype.getSuperValue=http://www.mamicode.com/function(){> 

使用原型链进行继承,对象继承的东西都是共享的。此时,使用对象修改继承的属性,即是直接修改父类原型里的属性,则其他对象的这个属性也会发生改变。

除非有特殊情况,不然原型链只可用于实现方法继承。

另外,现在instance.constructor 指向SuperType,因为instance的原型是SuperType的实例。

借用构造函数(也叫伪造对象或经典继承)
function SuperType(name){
    this.name=name;
}

function SubType(name,age){
    SuperType.call(this,name);
    this.age=age;
}

var instance1=new SubType("Lufy",18);
var instance2=new SubType("Natro",16);

使用借用构造函数方法继承得来的东西,对象间不共享。这样的话就没有函数复用,造成资源浪费。

借用构造函数可用于继承父类属性,并且很少单独使用。

组合继承
function SuperType(name){
    this.name=name;
    this.colors=["red","blue","green"]
}
SuperType.prototype.sayName=function(){
    alert(this.name);
};

function SubType(name,age){
    SuperType.call(this,name);
    this.age=age;
}
SubType.prototype=new SuperType();
SubType.prototype.sayAge=function(){
    alert(this.age);
}

var instance1=new SubType("Lufy",22);
instance1.colors.push("black");
var instance2=new SubType("Naruto",20);

组合使用原型链和借用构造函数实现继承。使属性在子类实例中;方法则需要沿着原型链查到父类原型,实现了函数复用。

原型式继承
var person={
    name:"Nicholas",
    friends:["Shelby","Court","Van"]
};

var anotherPerson=Object.create(person);
anotherPerson.name="Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson=Object.create(person,{
    name:{
        value:"Linda"
    }
});
yetAnotherPerson.friends.push("BarBie");

console.info(anotherPerson.friends);    //["Shelby", "Court", "Van", "Rob", "BarBie"]

其中,Object.create就是规范化的这个函数:

function object(o){
    function F(){};
    F.prototype=o;
    return f();
}

只想让一个对象和另一个对象类似,可以使用 原型式继承。

寄生式继承
var person={
    name:"Jack",
    age:20
};

var anotherPerson=createAnother(person);
anotherPerson.sayName();
寄生组合式继承

组合式继承非常经典,但它也有不足。它的问题就是:不论在什么情况下,都会调用两次超类型构造函数,浪费了性能。

function SuperType(name){
    this.name=name;
    this.colors=["red","blue","green"]
}
SuperType.prototype.sayName=function(){
    alert(this.name);
};

function SubType(name,age){
    SuperType.call(this,name);               //第二次调用SuperType()
    this.age=age;
}
SubType.prototype=new SuperType();           //第一次调用SuperType()
SubType.prototype.sayAge=function(){
    alert(this.age);
}

var instance1=new SubType("Lufy",22);
instance1.colors.push("black");
var instance2=new SubType("Naruto",20);

为了弥补这个缺陷,诞生了 “寄生组合式继承”:

function inheritPrototype(subType,superType){
    var prototype=Object(superType.prototype);
    prototype.constructor=subType;
    subType.prototype=prototype;
}

function SuperType(name){
    this.name=name;
    this.colors=["red","blue","green"];
}
SuperType.prototype.sayName=function(){
    alert(this.name);
};

function SubType(name,age){
    SuperType.call(this,name);        //调用SuperType构造函数
    this.age=age;
}
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge=function(){
    alert(this.age);
};

var p1=new SubType("Jack",20);

此方法的高效体现于其只调用一次超类构造函数。

开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。