类的继承
创建一个父类的构造函数
// 创建一个Animal的构造函数
function Animal(name) {
this.name = name || 'Animal'
this.sleep = function () {
console.log(this.name + " is sleeping");
}
}
原型链继承
优点:基于原型链,既是父类的实例,也是子类的实例
缺点:无法实现多继承
重点:子类型的原型指向父类型实例,子类型原型的构造属性设置为子类型
//创建一个子类Dog
function Dog(name) {
this.name = name || 'Dog'
}
// 子类型的原型指向父类型实例
Dog.prototype = new Animal()
// 子类型原型的构造属性设置为子类型
Dog.prototype.constructor = Dog
var d = new Dog()
d.sleep(); //Dog is sleeping
console.log(d instanceof Animal); //true
console.log(d instanceof Dog); //true
构造函数继承
优点:可以实现多继承
缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法
重点:父类.call(this,父类属性)
function Cat(name,age){
Animal.call(this,name)
this.age = age || 0
}
var c = new Cat('tom',1)
c.sleep() //tom is sleeping
console.log(c.age); //1
console.log(c instanceof Cat); //true
console.log(c instanceof Animal); //flase
组合继承 原型链继承+构造函数继承
特点:可以继承实例属性/方法,也可以继承原型属性/方法
缺点:调用了两次父类构造函数,生成了两份实例
function Monkey(name,price){
Animal.call(this,name)
this.price = price || 100
}
Monkey.prototype = new Animal()
Monkey.prototype.constructor = Monkey
Monkey.prototype.sayName = function(){
console.log("My name is "+this.name);
}
var m = new Monkey('bob')
m.sleep() //bob is sleeping
m.sayName() //My name is bob
console.log(m instanceof Animal); //true
console.log(m instanceof Monkey); //true
寄生组合继承
通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性
重点:1、创建一个没有实例方法的类 2、把该实例作为子类的原型
function Pig(name, color) {
Animal.call(this, name)
this.color = color || 'white'
}
(function () {
// 创建一个没有实例方法的类
var Super = function () { }
Super.prototype = Animal.prototype
// 把实例作为子类的原型
Pig.prototype = new Super()
})()
var p = new Pig('佩奇', 'pink')
p.sleep() //佩奇 is sleeping
console.log(p instanceof Pig); //true
console.log(p instanceof Animal); //true