1.构造函数继承
function Parent1() {
this.name = 'parent1'
}
function Child1() {
Parent1.call(this)
this.type = 'child1'
}
缺点:这种方法并没有继承Parent.prototype上的方法
2.利用原型链继承
function Parent2() {
this.name = 'parent2'
this.play = [1, 2, 3]
}
Parent2.prototype.say = [2, 3, 4]
function Child2() {
this.type = 'child2'
}
Child2.prototype = new Parent2()
var s1 = new Child2()
var s2 = new Child2()
s1.play.push(4)
console.log(s1.play, s2.play)
console.log(s1.say, s2.say)
缺点:改一个对象的属性,会改变其他对象属性
3.组合模式
function Parent3() {
this.name = 'parent3'
this.play = [1, 3, 9]
}
function Child3() {
Parent3.call(this)
this.type = 'child3'
}
Child3.prototype = new Parent3()
var s5 = new Child3()
var s6 = new Child3()
s5.play.push(10010)
console.log(s5.play, s6.play)
缺点:实例化子类的时候,父类构造函数执行了两次
4.组合继承优化
function Parent4() {
this.name = 'parent4'
this.play = [1, 3, 9]
}
function Child4() {
Parent4.call(this)
this.type = 'child3'
}
Child4.prototype = Parent4.prototype
var s7 = new Child4()
var s8 = new Child4()
s7.play.push(999)
console.log(s7.play, s8.play)
console.log(s7 instanceof Child4, s8 instanceof Parent4)//true true
console.log(s7.constructor)//Parent4
缺点:子类实例的隐式原型(_ proto _)的constructor指向父类构造函数
5.组合继承再优化(完美写法)
function Parent5() {
this.name = 'parent3'
this.play = [1, 3, 9]
}
function Child5() {
Parent3.call(this)
this.type = 'child3'
}
Child5.prototype = Object.create(Parent5.prototype)
Child5.prototype.constructor = Child5
var s9 = new Child5()
var s10 = new Child5()
s7.play.push(999)
console.log(s9.play, s10.play)
console.log(s9 instanceof Child5, s10 instanceof Parent5)//true true
console.log(s9.constructor)//Child5