JavaScript的继承方式
1.原型链继承
function superType(){
this.color = ['red','green','yellow'];
}
function subType(){
}
// 继承了SuperType
subType.prototype = new superType();
缺点:(1).包含引用类型值原型属性会被所有实例共享,原型的属性会变成现在原型的属性.
(2).没有办法在不影响所有对象实例的情况下,给超类型的构造函数传参。
注意:在通过原型链实现继承时,不能使用对象字面量创建原型方法,因为这样做会重写原型
2. 借用构造函数继承
在子类构造函数内部调用超类构造函数
function superType(){
this.color = ['red','green','yellow'];
}
function subType(){
superType.call(this);
this.age = 29; //为了确保SubType构造函数不会重写子类型的属性,可以在调用超类型构造函数之后,再添加应该在子类型中定义的属性。
}
优点:相比较原型链继承,可以在子类构造函数中向超类构造函数传递参数
缺点:方法都在构造函数中,无法实现函数的复用
3.组合继承
使用原型链实现对原型属性和方法的继承,使用构造函数实现对实例属性的继承。
function superType(name){
this.name = name;
this.color = ['red','green','yellow'];
}
superType.prototype.sayName = function (){
console.log(this.name)
}
function subType(name,age){
// 继承属性
superType.call(this,name);
this.age = age;
}
// 继承方法
superType.prototype = new SuperType();
superType.prototype.constructor = subType;
优点:组合继承避免了原型链和借用构造函数的缺陷,融合了他们的优点,而且instanceof和isPrototypeOf()可以识别基于组合继承创建的对象。
4.原型式继承
借助原型基于已有的对象创建对象,同时还不必因此创建自定义类型。
var person = {
name:'Nicholas',
friends:['Sam','Amy','Sue']
}
var anotherPerson = Object.create(person);
ECMAScript5通过新增的Object.create()规范了原型式继承。这个方法接受两个参数,一个用作新对象原型的对象和(可选的)一个新对象定义额外属性的对象。
优点:很简单的实现了让一个对象与另外一个对象保持类似的情况。
缺点:包含包含引用类型值的属性始终都会共享相应的值,就像使用原型模式一样。
5. 寄生式继承
创建一个仅用于封装继承过程的函数,该函数内部以某种方式来增强对象,最后再通过像真的是它做了所有工作一样返回对象。
function createAnotherPerson(original){
var clone = Object.create(original); // 通过这个对象创建一个新对象
clone.sayHi = function(){ //以某种方式来增强对象
console.log('Hi')
}
return clone;
}
在主要考虑对象而不是自定义类型和构造函数的情况下,寄生式继承也是一种有用的模式。
6.寄生组合式继承
通过借用构造函数来继承属性,通过原型链混成的方法来继承方法。不必为了指定子类型的原型而调用超类型的构造函数。本质就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。
function inheritPrototype(subType,superType){
var prototype = Object.create(superType.prototype)
prototype.constructor = subType
subType.prototype = prototype
}
function superType(name){
this.name = name;
this.color = ['red','green','yellow'];
}
superType.prototype.sayName = function(){
console.log(this.name);
}
function subType(name,age){
superType.call(this,name);
this.age = age;
}
inheritPrototype(subType,superType)
subType.sayHi = function(){
console.log(this.age)
}
优点:只调用一次构造函数,避免在subType上面创建不必要的、多余的属性。与此同时,原型链还能保持不变。被开发人员认为是最理想的继承范式。