構造函數式繼承函數
function Parent(n,walk){ this.name = n; } Parent.prototype.a = 'a'; function Child(name){ //子類繼承父類name屬性 Parent.call(this,name); } let baby = new Child('baby'); // baby baby.a; //undefined
構造函數缺點:子類沒法繼承父類原型對象上的屬性,兩個類的原型對象是相互獨立的。子類只能繼承構造函數掛載在實例上的屬性;this
原型鏈繼承
實現原理:將子類原型對象變爲父類的實例,則能夠繼承它的原型對象,解決了構造函數的缺點prototype
function Parent(){} Parent.prototype.a = 'a'; Parent.prototype.array = [1,2,3]; function Child(){} Child.prototype = new Parent() (new Child()).__proto__ === new Parent(); //true // 子類實例的原型對象等於父類的實例,也就是說子類實際上等於父類的實例 (new Child()).__proto__.__protp__ === Parent.prototype //true //用過原型鏈繼承,子類實例的原型(父類實例)的原型的對象等於父類的原型對象 Child.prototype.__proto__ === Parent.prototype //true //baby.__proto__.__proto__ = Parent.prototype 由此可知子類實例baby的原型的原型等於 父類的原型 let baby = new Child(); baby.__proto__ === Child.prototype //true baby.__proto__.__proto__ = Parent.prototype //true let anotherbaby = new Child(); baby.a;//a baby.array;// [1,2,3] anotherbaby.array.push(4); //由於baby和anotherbaby的原型都指向父類原型,因此當屬性值爲引用類型時一個修改了會影響另一個 baby.array // [1,2,3,4]
構造原型式繼承
組合繼承方式能夠解決實例繼承原型對象屬性互相影響的問題code
function Parent(name){ this.name=name //引用類型不要放到原型對象上 this.arr = arr; } function Child(name){ //繼承父類的構造函數 Parent.call(this,name,arr) } //用Object.create()接口從新建立一個和Parent.prototype同樣的對象 let prototype = Object.create(Parent.peototype) //可是這時prototype.constructor = Parent的構造函數 須要改成Child prototype.constructor = Child //繼承父類的原型對象 Child.prototye = prototype