首先定义一个父类Animal
function Animal(name){
// 属性
this.name = name;
// 方法
this.sleep = function(){
console.log(this.name + '正在睡觉');
}
}
// 原型方法(prototype)
Animal.prototype.eat = function(food){
console.log(this.name + '正在吃' + food);
}
1、原型链继承
核心:将父类实例作为子类原型
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// test
var cat = new Cat();
console.log(cat.name); //cat
console.log(cat.eat('fish')); //cat正在吃fish
console.log(cat.sleep()); // cat正在睡觉
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
优点: 简单、易实现 缺点: 无法实现多继承、无法向父类构造函数传参
2、构造继承
核心:使用父类构造函数增强子类实例,通过call绑定
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
// test
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.eat('fish')); //error
console.log(cat.sleep()); //Tom正在睡觉
console.log(cat instanceof Animal); //false
console.log(cat instanceof Cat); //true
优点: 可以实现多继承 缺点: 无法继承原型链上的方法
3、实例继承
核心:通过new创建父类实例,并添加新特性
function Cat(name){
var animal = new Animal();
animal.name = name || 'Tom';
return animal;
}
// test
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.eat('fish')); //Tom正在吃fish
console.log(cat.sleep()); //Tom正在睡觉
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //false
优点: 不限制调用方式 缺点: 实例是父类的实例,不是子类的实例
4、拷贝继承
核心:通过for…in…拷贝父类的所有内容
function Cat(name){
var animal = new Animal();
for(var i in animal){
Cat.prototype[i] = animal[i];
}
Cat.prototype.name = name || 'Tom';
}
// test
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.eat('fish')); //Tom正在吃fish
console.log(cat.sleep()); //Tom正在睡觉
console.log(cat instanceof Animal); //false
console.log(cat instanceof Cat); //true
优点: 支持多继承 缺点: 占内存
5、组合继承
核心:调用父类构造(call),继承父类内容,并通过父类实例(new)实现继承
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
// test
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.eat('fish')); //Tom正在吃fish
console.log(cat.sleep()); //Tom正在睡觉
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
优点: 函数可复用 缺点: 调用两次父类构造函数,消耗内存
6、寄生组合继承
核心:通过寄生方式,去掉父类实例属性,在调用两次父类构造时不会初始化两次
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(
function(){
var Super = function(){};
Super.prototype = Animal.prototype;
Cat.prototype = new Super();
}
)();
// test
var cat = new Cat();
console.log(cat.name); //Tom
console.log(cat.eat('fish')); //Tom正在吃fish
console.log(cat.sleep()); //Tom正在睡觉
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
优点: 完美 缺点: 实现复杂