javascript繼承的幾種方法


繼承是面向對象編程中很重要的概念,在其它面向對象的語言中大都很簡單,例如java中有關鍵詞extends來實現

javascript語言在ES6也新增了extends關鍵詞可以實現繼承,用法與java其實大同小異:

 class Animal {
     constructor(props) {
         this.name = props.name
     }
     eat(){
         console.log(`${this.name} 要吃東西`)
     }
 }    
 class Dog extends Animal {
     constructor(props) {
         //調用實現父類的構造函數
         super(props);
         this.type = props.type
     }
     run(){
         console.log(`${this.name}要跑了`)
     }
 }
 
 const xiaobao = new Dog({name:"xiaobao"})
 console.log(xiaobao.eat(),xiaobao.run())

如果不用class 和extends關鍵詞呢?

要實現繼承,那么首先要定義一個被繼承的父類:

function Animal(name){
    this.type = "Animal"
    this.array = [1,2,3]
}
Animal.prototype.eat = function(type){
    console.log(this.name +"喜歡吃"+type)
}

1.構造函數

  利用call/apply方法改變函數上下文實現繼承,這種辦法有很明顯的缺點:不能繼承父類的原型的屬性或方法

function Dog(name){
    Animal.call(this)
    this.type = "dog"
    this.name = name
    
}
var xb = new Dog("小寶")
xb.type // dog
xb.array // [1,2,3]
xb.eat('骨頭') // Uncaught TypeError: (intermediate value).eat is not a function

2.原型鏈

  使子類原型對象指向父類的實例以實現繼承,缺點是會共用原型,不能多繼承,當有多個實例時數據會共通,這當然不是我們想要的。

function Dog(name){
    this.type="dog"
    this.name = name
}

Dog.prototype = new Animal()

var xb = new Dog("小寶")
var dd = new Dog("點點")

xb.array // [1,2,3]
dd.array // [1,2,3]
xb.array.push(4)

xb.array // [1,2,3,4]
dd.array // [1,2,3,4]

3.組合繼承

  調用父類構造函數,再使子類原型對象指向父類的實例,缺點是會調用兩次父類構造函數

function Dog(name){
    Animal.call(this)
    this.type="dog"
    this.name = name
}
Dog.prototype = new Parent3()

4.組合繼承--優化版

  將子類的原型指向父類的原型的對象(將父類的原型用Object.create()處理下,將子父的構造函數隔離開,沒有這一步將會造成父類的構造函數被覆蓋),再修復constructer,將子類構造函數賦給子類的原型的構造函數。

function Dog(name){
    Animal.call(this)
    this.type="dog"
    this.name = name
}
Dog.prototype = Animal.prototype
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog

后面兩種方式推薦使用,沒有什么明顯的缺點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM