# 原型链继承

function Animal(color) {
	this.species = 'animal'
	this.color = color
	this.type = []
}

function Dog() {
	this.name = 'dog'
}

Dog.prototype = new Animal('white')

var dog = new Dog()
console.log(dog.name);

// 引用缺陷
dog.type.push('dog')
var dog2 = new Dog()
console.log(dog2.type);

// 无法为不同实例初始化继承属性
console.log(dog.color);
console.log(dog2.color); 

该继承的有两个缺点:引用缺陷和无法为不同的实例初始化继承来的属性。

  • 引用缺陷是指,如果父类中的属性是引用类型的,子类继承了这个属性,则对一个子类实例更改了该引用类型,会影响其他子类实例,上述例子中,对dog实例更改了type引用属性,也影响了dog2实例中type的结果;

  • 无法为不同实例初始化继承成来的属性体现在为所有的Dog实例的color都只能为white。

# 借用构造函数继承(经典继承)

构造函数继承方式可以避免类式继承的缺陷。但是无法共享父类方法。下面代码输出中,dog和dog2的color和type都不一样,但是父类的hello方法无法调用。每次创建对象都会创建一遍方法。并且无法使用instanceof判断。

function Animal(color) {
	this.color = color
	this.type = []
}

Animal.prototype.hello = function() {
	console.log('hello');
}

function Dog(color) {
	Animal.apply(this, arguments)
}

var dog = new Dog('white')
dog.type.push('dog')

var dog2 = new Dog('black')
dog2.type.push('dog2')

console.log(dog.color);
console.log(dog.type);
console.log(dog2.color);
console.log(dog2.type);
dog.hello() //报错

# 组合继承

组合继承就是结合类式继承和构造函数继承的优点。缺点是会调用两次父构造函数,导致下面Dog.prototype中有color属性,dog中也有color属性。

function Animal(color) {
	this.color = color
	this.type = []
}

Animal.prototype.hello = function() {
	console.log('hello');
}

function Dog(color) {
	Animal.apply(this, arguments)
}

Dog.prototype = new Animal()

var dog = new Dog('white')
dog.type.push('dog')

var dog2 = new Dog('black')
dog2.type.push('dog2')

console.log(dog.color);
console.log(dog.type);
console.log(dog2.color);
console.log(dog2.type);
dog.hello()

# 寄生组合式继承

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;
}
// 关键的三步
var F = function () {};
 
F.prototype = Parent.prototype;
 
Child.prototype = new F();
 
 
var child1 = new Child('kevin', '18');
 
console.log(child1);

关键的三步保证了原型链的同时,消去了new Parent()带来的多余的属性。