javaScript繼承

原型

我個建立的每個函數都有一個prototype(原型)屬性, 這個屬性是一個指針,指向一個對象。而這個對象的做用是包含由特定類型的全部實例共享的屬性和方法。使用原型的好處是能夠讓全部實例共享它所包含全部屬性和方法。換句話說,沒必要在構造函數中定義對象的實例的信息,而是能夠將這些信息添加到原型對象中。(紅寶書)

繼承的6種方法

繼承分ES6和ES5的方法,ES6的方法很簡單,就是extends,可是隻知道這個方法是不合格的。下面說說ES5的方法,共有:
原型鏈繼承、借用構造函數繼承、組合式繼承、寄生式繼承、繼生組合式繼承javascript

  1. 原型鏈繼承

    讓子類的原型等行父類的實例,當子類實例找不到對應的屬性和方法時,就會向父類實例上找。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

  • 全部子類的實例的原型都是引用同一個Parent的實例,當其中一個子類實例將原型中的引用類型數據更改時,其餘實例對應的數據也會改變
  • 在建立子類實例時不能向Parent傳參
  1. 借用構造函數函數

    在子類的構造函數中調用父類構造函數(用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

    • 繼承不到父類原型上的屬性和方法
    • 方法都在構造函數中定義, 每次建立都會生成一遍方法
  2. 組合繼承指針

    將原型鏈繼承和借用構造函數繼承(經典繼承)組合起來。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')
  3. 寄生式繼承對象

    建立一個實現繼承的函數,以某種方式加強對象,而後返回這個對像.繼承

    function createAnother(obj) {
      const clone = Object(obj)
      clone.sayHi = function() {
        console.log('hi')
      }
      return clone
    }
  4. 寄生組合式繼承

    解決組合繼承會調用兩次父類構造函數的問題(效率問題), 找一箇中轉的空函數來執行

    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
相關文章
相關標籤/搜索