成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS 繼承的實現(xiàn)

張紅新 / 642人閱讀

摘要:構造函數(shù)繼承遍歷通過對象冒充實現(xiàn)繼承,實際上是在構造函數(shù)中,通過獲取父類中的所有屬性,并保存到自身對象中,這樣則可以調用父類的屬性和方法了。

JS從誕生之初本就不是面向對象的語言。

如何在JS中實現(xiàn)繼承,總結而言會有四種寫法。

構造函數(shù)繼承
function Animal(name) {
    this.name = name
        
    this.sayName = function() {
        console.log(this.name)
    }
}
    
function Dog(name, hobby) {
    // 遍歷
    let ani = new Animal(name)
    for(let p in ani) {
        if (ani.hasOwnProperty(p)) {
            this[p] = ani[p]
        }
    }
        
    this.hobby = hobby
}
    
let dog1 = new Dog("xiaohei", "bone")
let dog2 = new Dog("fofo", "bone and fish")
console.log(dog1.sayName()) // xiaohei
console.log(dog2.sayName()) // fofo

通過對象冒充實現(xiàn)繼承,實際上是在構造函數(shù)中,通過獲取父類中的所有屬性,并保存到自身對象中,這樣則可以調用父類的屬性和方法了。這里forin的方式遍歷父類屬性,因為forin會遍歷公開的屬性和方法,所以通過hasOwnProperty控制寫入當前對象的范圍。否則則會將所有屬性全部變?yōu)樗接袑傩浴?/p>

這樣做有一個缺點就是,無法訪問父類中的公開方法和屬性(prototype中的方法)

Animal.prototype.sayHobby = function() {
    console.log(this.hobby)
}
dog1.sayHobby() // VM2748:1 Uncaught TypeError: dog1.sayHobby is not a function at :1:6

代碼優(yōu)化

在子類中,既然是需要獲取父類的私有屬性,則可以使用callapply,當調用父類的方法的時候,改變當前上下文為子類對象,則子類對象就可以獲取到了父類的所有私有屬性。

function Animal(name) {
    this.name = name
        
    this.sayName = function() {
        console.log(this.name)
    }
}
    
function Dog(name, hobby) {
    // 更改構造函數(shù)的上下文
    Animal.call(this, name)
    
    this.hobby = hobby
}
    
let dog1 = new Dog("xiaohei", "bone")
let dog2 = new Dog("fofo", "bone and fish")
console.log(dog1.sayName()) // xiaohei
console.log(dog2.sayName()) // fofo
類式繼承
function Animal(name) {
    this.name = name || "animal"
    this.types = ["cat", "dog"]
    
    this.sayTypes = function() {
        console.log(this.types.join("-"))
    }
}
Animal.prototype.sayName = function() {
    console.log(this.name)
}

function Dog(name) {
    this.name = name    
}
Dog.prototype = new Animal("animal")

let dog1 = new Dog("xiaohei")
dog1.sayName() // xiaohei

let dog2 = new Dog("feifei")
dog2.sayName() // feifei

這種繼承方式是通過對子類的prototype.__proto__引用父類的prototype,從而可以讓子類訪問父類中的私有方法和公有方法。詳情可以查看關鍵字new的實現(xiàn)。

類式繼承會有兩方面的缺點

引用陷阱-子類對象可以隨意修改父類中的方法和變量,并影響其他子類對象

dog1.types.push("fish")
console.log(dog1.types) // ["cat", "dog", "fish"]
console.log(dog2.types) // ["cat", "dog", "fish"]

無法初始化構造不同的實例屬性

這個主要是由于類式繼承,是通過Dog.prototype = new Animal("animal")實現(xiàn)的,我們只會調用一次父類的構造函數(shù)。所以只能在子類中從寫父類的屬性,如上的name屬性,在子類中需要重寫一次。

組合繼承

組合繼承,即結合以上兩種繼承方式的優(yōu)點,拋棄兩者的缺點,而實現(xiàn)的一種組合方式

function Animal(name) {
    this.name = name
    this.types = ["dog", "cat"]
}
Animal.prototype.sayName = function() {
    console.log(this.name)
}

function Dog(name, hobby) {
    // 獲取私有方法并調用父類的構造函數(shù),并傳遞構造函數(shù)的參數(shù),實現(xiàn)初始化不同的構造函數(shù)
    Animal.call(this, name)
    this.hobby = hobby
}
// 子類實例可以訪問父類prototype的方法和屬性
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
Dog.prototype.sayHobby = function() {
    console.log(this.hobby)
}

// test instance of dog1
let dog1 = new Dog("xiaohei", "bone")
dog1.sayName() // xiaohei
dog1.sayHobby() // bone
dog1.types.push("ant") // types: ["dog", "cat", "ant"]

// test instance of dog2
let dog2 = new Dog("feifei", "fish")
dog2.sayName() // feifei
dog2.sayHobby() // fish
dog2.types // ["dog", "cat"]

組合模式,解決了使用構造函數(shù)繼承類式繼承帶來的問題,算是一種比較理想的解決繼承方式,但是這里還有一些瑕疵,調用了兩次父類(Animal)的構造函數(shù)。

所以為了解決這個問題,進行了優(yōu)化,產生了

文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉載請注明本文地址:http://systransis.cn/yun/101071.html

相關文章

  • JavaScript繼承方式詳解

    摘要:可以通過構造函數(shù)和原型的方式模擬實現(xiàn)類的功能。原型式繼承與類式繼承類式繼承是在子類型構造函數(shù)的內部調用超類型的構造函數(shù)。寄生式繼承這種繼承方式是把原型式工廠模式結合起來,目的是為了封裝創(chuàng)建的過程。 js繼承的概念 js里常用的如下兩種繼承方式: 原型鏈繼承(對象間的繼承) 類式繼承(構造函數(shù)間的繼承) 由于js不像java那樣是真正面向對象的語言,js是基于對象的,它沒有類的概念。...

    Yangyang 評論0 收藏0
  • js原型和繼承

    摘要:舉例說明組合繼承組合繼承利用原型鏈借用構造函數(shù)的模式解決了原型鏈繼承和類式繼承的問題。示例組合式繼承是比較常用的一種繼承方法,其背后的思路是使用原型鏈實現(xiàn)對原型屬性和方法的繼承,而通過借用構造函數(shù)來實現(xiàn)對實例屬性的繼承。 對js原型和繼承的理解一直處于不懂-懂-不懂-懂-不懂。。。的無限循環(huán)之中,本來打算只是簡單總結下js繼承方式,可看了些網(wǎng)上的資料后,發(fā)現(xiàn)又不懂繼承了。。。這篇文章只...

    Hujiawei 評論0 收藏0
  • JS面向對象之五 【繼承

    摘要:首先為了模擬類創(chuàng)建對象的功能搞出了構造函數(shù)。也就是名字膚色膚色這里是繼承里的自有屬性生命值這里繼承的共有屬性的方法攻擊力兵種美國大兵攻擊防御死亡膚色 JS面向對象之五 【繼承】 我們已經(jīng)準備了很多前置知識,包括 原型鏈,對象和對象之間的關系 this,對象和函數(shù)之間的關系 new, 用函數(shù)批量創(chuàng)建特定的對象的語法糖 JS面向對象的前世今生 我們說,面向對象是一種寫代碼的套路。因為如...

    genefy 評論0 收藏0
  • JS面向對象程序設計之繼承實現(xiàn)-組合繼承

    摘要:實現(xiàn)思路使用原型鏈實現(xiàn)對原型方法和方法的繼承,而通過借用構造函數(shù)來實現(xiàn)對實例屬性的繼承。繼承屬性繼承方法以上代碼,構造函數(shù)定義了兩個屬性和。 JS面向對象的程序設計之繼承的實現(xiàn)-組合繼承 前言:最近在細讀Javascript高級程序設計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯誤,會非常感謝您的指出。文中絕大部分內容引用自《Java...

    antz 評論0 收藏0
  • 《javascript高級程序設計》 繼承實現(xiàn)方式

    摘要:寄生式繼承的思路與寄生構造函數(shù)和工廠模式類似,即創(chuàng)建一個僅用于封裝繼承過程的函數(shù),該函數(shù)在內部已某種方式來增強對象,最后再像真的是它做了所有工作一樣返回對象。 這篇本來應該是作為寫JS 面向對象的前奏,只是作為《javascript高級程序設計》繼承一章的筆記 原型鏈 code 實現(xiàn) function SuperType() { this.colors = [red,blu...

    cppprimer 評論0 收藏0
  • JS類與類繼承

    摘要:首先捋清楚類和對象的關系類比如人類,指的是一個范圍對象比如某個人,指的是這個范圍中具體的對象中的作為構造函數(shù)時,就是一個類,通過操作符,可以返回一個對象。 JS中的類與類的繼承 我們知道,JS中沒有類或接口的概念,即不能直接定義抽象的類,也不能直接實現(xiàn)繼承。不過,為了編程的方便,我們可以在 JS 中模擬類和繼承的行為。首先捋清楚類和對象的關系: 類:比如人類,指的是一個范圍; ...

    Tangpj 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<