我個建立的每個函數都有一個prototype(原型)屬性, 這個屬性是一個指針,指向一個對象。而這個對象的做用是包含由特定類型的全部實例共享的屬性和方法。使用原型的好處是能夠讓全部實例共享它所包含全部屬性和方法。換句話說,沒必要在構造函數中定義對象的實例的信息,而是能夠將這些信息添加到原型對象中。(紅寶書)
繼承分ES6和ES5的方法,ES6的方法很簡單,就是extends
,可是隻知道這個方法是不合格的。下面說說ES5的方法,共有:
原型鏈繼承、借用構造函數繼承、組合式繼承、寄生式繼承、繼生組合式繼承javascript
讓子類的原型等行父類的實例,當子類實例找不到對應的屬性和方法時,就會向父類實例上找。java
function Parent() { this.name = 'parent' } Parent.prototype.sayName = function() { console.log(this.name) } function Child() { this.name = 'child' } Child.prototype = new Parent() // 最後能夠將constructor改回來 Child.prototype.constructor = Child
原型鏈繼承的缺點:app
借用構造函數函數
在子類的構造函數中調用父類構造函數(用call / apply將調用的this指向子類實例),這樣既避免了實例之間共享同一個原型,又能夠向父類構造函數傳參。解決了原型鏈繼承的兩個問題。this
function Parent(name, age) { this.style = [1, 2, 3] this.name = name this.age = age } Parent.prototype.sayStyle = function() { console.log(this.style) } function Child(name, age) { Parent.call(this, name, age) } let child = new Child('child', 11) child.style // [1, 2, 3] child.name // 'child' child.sayStyle() // 報錯 is not a function, 由於子實類沒法繼承到Parent原型上的方法
借用構造函數的缺點prototype
組合繼承指針
將原型鏈繼承和借用構造函數繼承(經典繼承)組合起來。code
function Parent(name) { this.style = [1, 2, 3] this.name = name } Parent.prototype.sayStyle = function() { console.log(this.style) } function Child(name) { Parent.call(this, name) } Child.prototype = new Parent() Child.prototype.constructor = Child let child = new Child('child')
寄生式繼承對象
建立一個實現繼承的函數,以某種方式加強對象,而後返回這個對像.繼承
function createAnother(obj) { const clone = Object(obj) clone.sayHi = function() { console.log('hi') } return clone }
寄生組合式繼承
解決組合繼承會調用兩次父類構造函數的問題(效率問題), 找一箇中轉的空函數來執行
function Parent(name) { this.name = name this.style = [1, 2, 3] } Parent.prototype.say = function() { console.log(this.style) } function Child(name, age) { Parent.call(this, name) this.age = age } // 中轉的空函數 function F() {} F.prototype = Parent.prototype Child.prototype = new F() Child.prototype.constructor = Child