參考http://www.reibang.com/p/1016160e91fe
原型繼承
缺點(diǎn): 子類(lèi)實(shí)例共享屬性,造成實(shí)例間的屬性會(huì)相互影響
function Parent1() {
this.name = ['super1']
this.reName = function () {
this.name.push('super111')
}
}
function Child1() {
}
Child1.prototype = new Parent1()
var child11 = new Child1()
var child12 = new Child1()
var parent1 = new Parent1()
child11.reName()
console.log(child11.name, child12.name) // [ 'super1', 'super111' ] [ 'super1', 'super111' ], 可以看到子類(lèi)的實(shí)例屬性皆來(lái)自于父類(lèi)的一個(gè)實(shí)例笑撞,即子類(lèi)共享了同一個(gè)實(shí)例
console.log(child11.reName === child12.reName) // true, 共享了父類(lèi)的方法
構(gòu)造函數(shù)繼承
缺點(diǎn): 父類(lèi)的方法沒(méi)有被共享,造成內(nèi)存浪費(fèi)
function Child2() {
Parent1.call(this)
}
var child21 = new Child2()
var child22 = new Child2()
child21.reName()
console.log(child21.name, child22.name) // [ 'super1', 'super111' ] [ 'super1' ], 子實(shí)例的屬性都是相互獨(dú)立的
console.log(child21.reName === child22.reName) // false, 實(shí)例方法也是獨(dú)立的皮获,沒(méi)有共享同一個(gè)方法
組合繼承
缺點(diǎn): 父類(lèi)構(gòu)造函數(shù)被調(diào)用兩次,子類(lèi)實(shí)例的屬性存在兩份麻诀。造成內(nèi)存浪費(fèi)
function Parent3() {
this.name = ['super3']
}
Parent3.prototype.reName = function() {
this.name.push('super31')
}
function Child3() {
Parent3.call(this) // 生成子類(lèi)的實(shí)例屬性(但是不包括父對(duì)象的方法)
}
Child3.prototype = new Parent3() // 繼承父類(lèi)的屬性和方法(副作用: 父類(lèi)的構(gòu)造函數(shù)被調(diào)用的多次献酗,且屬性也存在兩份造成了內(nèi)存浪費(fèi))
var child31 = new Child3()
var child32 = new Child3()
child31.reName()
console.log(child31.name, child32.name) // [ 'super3', 'super31' ] [ 'super3' ], 子類(lèi)實(shí)例不會(huì)相互影響
console.log(child31.reName === child32.reName) //true, 共享了父類(lèi)的方法
寄生繼承
完美:子類(lèi)都有各自的實(shí)例不會(huì)相互影響初家,且共享了父類(lèi)的方法
function Parent4() {
this.name = ['super4']
}
Parent4.prototype.reName = function() {
this.name.push('super41')
}
function Child4() {
Parent4.call(this) // 生成子類(lèi)的實(shí)例屬性(但是不包括父對(duì)象的方法)
}
Child4.prototype = Object.create(Parent4.prototype) // 該方法會(huì)使用指定的原型對(duì)象及其屬性去創(chuàng)建一個(gè)新的對(duì)象
var child41 = new Child4()
var child42 = new Child4()
child41.reName()
console.log(child41.name, child42.name) //[ 'super4','super41' ] [ 'super4' ], 子類(lèi)實(shí)例不會(huì)相互影響
console.log(child41.reName === child42.reName) //true, 共享了父類(lèi)的方法
ES6 class
類(lèi)似于寄生繼承
class Parent5 {
constructor() {
this.name = ['super5']
}
reName() {
this.name.push('new 5')
}
}
class Child5 extends Parent5 {
constructor() {
super()
}
}
var child51 = new Child5()
var child52 = new Child5()
child51.reName()
console.log(child51.name, child52.name) // [ 'super5', 'new 5' ], 子類(lèi)實(shí)例不會(huì)相互影響
console.log(child51.reName === child52.reName) //true, 共享了父類(lèi)的方法