面向对象的程序设计之继承

如下是几种js中实现继承的方式方法,它们也是各自有各自的优缺点,选择哪种根据本身的应用而定,最适合本身的才是最好的.javascript

经过原型链继承

function SuperType(){
    this.name = 'yahualingfeng';
}

SuperType.prototype.friends = ['David','Bob','Lucy'];
SuperType.prototype.sayName = function(){
    
  alert(this.name);
  
};

function SubType(){
    this.age = 30;    
}

SubType.protoType = new SuperType();//经过原型对象继承SuperType

var subType1 = new SubType();
var subType2 = new SubType();

subType1.friends.push('Jake');

console.log(subType1.friends); // ['David','Bob','Lucy','Jake']
console.log(subType2.friends); // ['David','Bob','Lucy','Jake']

缺点:java

  • 引用类型的值在原型中会被全部实例共享.
  • 不能向超类的构造函数中传递参数

借用构造函数继承

借用构造函数继承是将超类(SuperType)全部的属性和方法都写在构造函数中,最后在函数(SubType)体内经过call方法调用超类.函数

function SuperType(){
    this.name = 'yuhualingfeng';
    this.friends =['David','Bob','Lucy'];
    this.sayName = function(){
        alert(this.name);
    }
}

function SubType(){
    SuperType.call(this);
}

var subType = new SubType();
subType.sayName();

缺点:方法的定义都存在构造函数中,致使函数没法被复用.this

组合继承

组合继承是原型链继承和构造函数继承的结合体,结合了两者的优势,即实现了函数的复用,也不会致使引用类型值在多个实例中共享.prototype

function SuperType(){
    this.name='yuhualingfeng';
    this.friends=['David','Bob','Lucy'];
}
SuperType.prototype.sayName = function(){
    
    alert(this.name);

};

function SubType(){

    SuperType.call(this);

}

SubType.prototype = new SuperType();

var subType = new SubType();

缺点:code

  • 超类函数被执行了两次.
  • 超类构造函数SuperType自身的属性(name,friends)被重复定义,即出如今SubType的构造函数中,也出如今SubType的原型对象中.

原型继承

原型继承是继承自一个对象而不是引用类型.对象

function object(obj){
 function F(){}
 F.prototype = obj;
 return new F();
}

这里的object方法接收obj对象,并将对象赋值给一个空函数的原型,并返回空函数的实例.继承

var person = {
 name:'yuhualingfeng',
 friends:['David','Bob','Lucy']
};

var anotherPerson = object(person);
anotherPerson.name = 'Jake';
anotherPerson.friends.push('Marry');

console.log(anotherPerson.friends); //['David','Bob','Lucy','Marry']

console.log(person.friends); //['David','Bob','Lucy','Marry']

若是不想建立构造函数,只想让一个对象和另外一个对象保持一致的状况下,原型继承是彻底能够胜任的,不过有一点要注意的是,假如继承的属性值为引用类型时,仍是会相互影响的.ip

寄生继承

寄生继承是基于原型继承的基础上扩展本身的属性和方法.ci

function createrAnother(obj){
    var clone = object(obj);
    clone.sayHi=function(){
     alert('Hi!');
    }
    return clone;
}

var person = {
    name:'yuhualingfeng'
};

var anotherPerson = createAnother(person);

anohterPerson.sayHi();  // Hi

寄生继承也是和原型继承同样也是继承对象,并产出对象.

寄生组合继承

顾名思义,寄生组合继承是集寄生继承和组合继承的结合体,它结合了两者的优势.

//继承Supertype的原型对象
function inheritProtoType(SuperType,SubType){
 
     var prototype = object(SuperType.prototype);
     prototype.constructor = SubType;
     SubType.prototype = prototype;

}

function SuperType(){
    this.name = 'yuhualingfeng';
    this.friends = ['David','Bob','Lucy'];
}

function SubType(){
    ////继承Supertype的构造函数属性
    SuperType.call(this);
    this.age = 30;
}

inheritProtoType(SuperType,SubType);

var subType = new SubType();

寄生组合继承是前面几种继承思想碰撞在一块儿的产物,是执行效率最高也是应用面最广的.

总结

原型链继承是经过为原型对象赋值,不足之处为引用类型值会被多个实例共享,构造函数继承解决了原型链继承的问题,同时也暴露出新的问题是函数的复用没法实现,而后咱们结合两者的优缺点,构造出了组合继承,组合继承基本上知足了咱们想要的继承结果.
考虑到执行的效率,咱们构思出了寄生继承(基于原型继承),并将寄生继承组合继承结合,最终得出了继承的最优解决方案'寄生组合继承.

相关文章
相关标签/搜索