大致有 6 种 (各有利弊)
- 原型链继承
- 盗用(父类)构造函数继承
- 组合继承【原型链 + 盗用构造函数】
- 原型继承 【不需要事先创造构造函数】 (工厂)
- 寄生式继承 【拷贝原对象、增强副本、返回】 (工厂)
- 寄生式组合继承
<1> 原型链继承
让子类构造函数的原型对象指向父亲的实例对象。即
Child.prototype = new Parent()。这样依据原型链,子类实例对象的原型对象就是父亲的实例对象,就会拥有父类的属性和方法。
缺点:
- 所有实例共享同一个引用类型的属性
- 在 new Child() 实例时,不能向 Parent() 构造函数传参
<2> 盗用构造函数继承
在定义子类的构造函数时,在子类构造函数内部调用父类的构造函数,从而将父类属性继承到自己身上。
function Parent () {
this.names = ['kevin', 'daisy'];
}
function Child () {
Parent.call(this);
}
var child1 = new Child();
优点:
- 避免了引用类型的属性被所有实例共享
- 可以在 Child 中向 Parent 传参
缺点:
- 每次创建实例都会创建一遍方法。(
且继承不到父亲原型中的方法!!!!)
<3> 组合继承【原型链 + 盗用构造函数】
使用
原型链继承原型上的属性和方法,使用盗用构造函数继承实例自己的属性!!!
function Parent (name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function () {
console.log(this.name)
}
function Child (name, age) {
Parent.call(this, name);
this.age = age;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
var child1 = new Child('kevin', '18');
缺点:
- 效率问题,父类构造函数被调用了两次!!!
<4> 原型继承 【不需要事先创造构造函数,工厂模式】【适用于没有构造函数,只有想要继承的实例对象】
实现对象间属性和方法的共享,不需要单独创建父类、子类构造函数,也不需要再 new 出来子类的实例对象。思路就是:
创建一个空的构造函数 F(),把该构造函数的原型指向要继承的对象。然后返回 new F()
function createObj(o) {
function F(){}
F.prototype = o;
return new F();
}
缺点:
- 所有实例共享同一个引用类型的属性
<5> 寄生式继承 【拷贝原对象、增强副本、返回】
基本思路类似于寄生构造函数和工厂模式:创建一个实现继承的函数,在函数中先拷贝源对象,然后增强副本,然后返回新对象!!
function createObj (o) {
var clone = Object.create(o);
clone.sayName = function () {
console.log('hi');
}
return clone;
}
- 跟借用构造函数模式一样,每次创建对象都会创建一遍方法。
<6> 寄生式组合继承
用
盗用构造函数继承父类属性。用寄生的方法获取父亲原型的一个副本【不借助父类构造函数,区别于组合式继承】
function Parent (name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.getName = function () {
console.log(this.name)
}
// 盗用构造函数继承属性
function Child (name, age) {
Parent.call(this, name);
this.age = age;
}
// 寄生式+原型式 继承方法
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
function prototype(Child, Parent) {
var prototype = object(parent.prototype);
prototype.constructor = Child;
Child.prototype = prototype;
}
// 当我们使用的时候:
prototype(Child, Parent);
优点:
- 解决了组合继承【盗用构造函数 + 原型链】需要多次 new Parent() 的效率问题!!!