缺點: 子類實例共享屬性,形成實例間的屬性會相互影響函數
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' ], 能夠看到子類的實例屬性皆來自於父類的一個實例,即子類共享了同一個實例 console.log(child11.reName === child12.reName) // true, 共享了父類的方法
缺點: 父類的方法沒有被共享,形成內存浪費this
function Child2() { Parent1.call(this) } var child21 = new Child2() var child22 = new Child2() child21.reName() console.log(child21.name, child22.name) // [ 'super1', 'super111' ] [ 'super1' ], 子實例的屬性都是相互獨立的 console.log(child21.reName === child22.reName) // false, 實例方法也是獨立的,沒有共享同一個方法
缺點: 父類構造函數被調用兩次,子類實例的屬性存在兩份。形成內存浪費prototype
function Parent3() { this.name = ['super3'] } Parent3.prototype.reName = function() { this.name.push('super31') } function Child3() { Parent3.call(this) // 生成子類的實例屬性(可是不包括父對象的方法) } Child3.prototype = new Parent3() // 繼承父類的屬性和方法(反作用: 父類的構造函數被調用的屢次,且屬性也存在兩份形成了內存浪費) var child31 = new Child3() var child32 = new Child3() child31.reName() console.log(child31.name, child32.name) // [ 'super3', 'super31' ] [ 'super3' ], 子類實例不會相互影響 console.log(child31.reName === child32.reName) //true, 共享了父類的方法
完美:子類都有各自的實例不會相互影響,且共享了父類的方法code
function Parent4() { this.name = ['super4'] } Parent4.prototype.reName = function() { this.name.push('super41') } function Child4() { Parent4.call(this) // 生成子類的實例屬性(可是不包括父對象的方法) } Child4.prototype = Object.create(Parent4.prototype) // 該方法會使用指定的原型對象及其屬性去建立一個新的對象 var child41 = new Child4() var child42 = new Child4() child41.reName() console.log(child41.name, child42.name) //[ 'super4','super41' ] [ 'super4' ], 子類實例不會相互影響 console.log(child41.reName === child42.reName) //true, 共享了父類的方法
和寄生繼承實現的效果一致對象
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' ], 子類實例不會相互影響 console.log(child51.reName === child52.reName) //true, 共享了父類的方法