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

資訊專欄INFORMATION COLUMN

JS對象(3)經(jīng)典對象創(chuàng)建與繼承模式

hellowoody / 1809人閱讀

摘要:對象經(jīng)典對象創(chuàng)建與繼承模式組合模式創(chuàng)建對象中創(chuàng)建一個(gè)對象的方式多種多樣,每種方式都有自己缺點(diǎn)或者優(yōu)點(diǎn),具體的可以參考而組合使用構(gòu)造函數(shù)模式和原型模式來創(chuàng)建自定義類型算是最常見的方式了。

title: JS對象(3)經(jīng)典對象創(chuàng)建與繼承模式
date: 2016-09-28
tags: JavaScript

0x01 組合模式創(chuàng)建對象

JS 中創(chuàng)建一個(gè)對象的方式多種多樣,每種方式都有自己缺點(diǎn)或者優(yōu)點(diǎn),具體的可以參考____

而組合使用構(gòu)造函數(shù)模式和原型模式來創(chuàng)建自定義類型算是最常見的方式了。

在組合模式中,構(gòu)造函數(shù)用于定義實(shí)例屬性,而原型用于定義方法和共享的屬性。

如此,每個(gè)實(shí)例都會(huì)有自己的一份實(shí)例屬性的副本,又共享著對方法的引用。

function Person(name, age, job){
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["jack", "marli"]
}

Person.prototype = {
    // 使用字面量形式重寫原型
    constructor : Person,
    sayName : function(){
        console.log(this.name);
    }
}

var person1 = new Person("劉德華",54,"歌手 演員")
person1.friends.push("成龍")
var person2 = new Person("特朗普",60,"企業(yè)家 花花公子 總統(tǒng)")

console.log(person1.sayName()+"的朋友: "+person1.friends)
//劉德華的朋友: jack,marli,成龍
console.log(person2.name+"的朋友: " +person2.friends)
//特朗普的朋友: jack,marli

當(dāng)修改了 person1.friends 并不會(huì)影響到 person2.friends,因?yàn)樗鼈兎謩e引用了不同的數(shù)組。

現(xiàn)在,對 Person 的原型進(jìn)行如下修改:

Person.prototype = {
    // 使用字面量形式重寫原型
    constructor : Person,
    sex:"man",
    hobby:["woman","money","food"],
    sayName : function(){
        console.log(this.name);
    }
}

如上,我們新添加了 sexhobby 兩個(gè)共享屬性。

person1.sex = "woman"
console.log(person1.sex)
// woman
console.log(person2.sex)
// man

person1.hobby.push("reputation")
// ["woman", "money", "food", "reputation"]
console.log(person2.hobby)
// ["woman", "money", "food", "reputation"]

我們嘗試在 person1 中將 Person 原型里的 sex 修改為 woman,person2 并沒有受到影響,即使 sex 屬性是屬于 Person 原型中的共享屬性。這很容易理解,因?yàn)?Person 中的 sex 是字符串,即屬于六種原始類型中的一種。

但是,當(dāng)我門對 person1 中的 hobby 推入一個(gè)元素的時(shí)候,person2hobby 同樣被更改了。這也很容易理解,hobby 數(shù)數(shù)組,是引用類型的,且存在于 Person 的原型中,即它是共享屬性,那么在任何實(shí)例中的操作都會(huì)影響到原型中的共享屬性。

0x02 組合式繼承

作為經(jīng)典繼承模式,組合式繼承模式算是 JS 中使用最多的了。

其思想是使用原型鏈實(shí)現(xiàn)對原型屬性和方法的繼承,而通過借用構(gòu)造函數(shù)來實(shí)現(xiàn)對實(shí)例屬性的繼承。

function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","pink"];
}

SuperType.prototype = {
    // 重寫原型
    constructor: SuperType,
    // 將原型的構(gòu)造函數(shù)指向 SuperType
    job:["teacher","student"],
    sayName:function(){
        console.log(this.name)
    }
}


function SubType(name, age){
    
    SuperType.call(this, name); // **第二次調(diào)用 SuperType 構(gòu)造函數(shù)**
    // 繼承父類的實(shí)例屬性,也因此而覆蓋了原型繼承中的同名屬性
    this.age = age;
}

SubType.prototype = new SuperType(); // **第一次調(diào)用 Supertype 構(gòu)造函數(shù)**
// 此時(shí) SubType 的原型中將會(huì)包含 SuperType 的所有屬性和方法(包括實(shí)例屬性,共享屬性,以及共享方法)

SubType.constructor = SubType;

SubType.prototype.sayAge = function(){
    // 繼承而來的原型不能通過對象字面量的方式被重寫,即是添加了 constructor 屬性也沒用
    console.log(this.age)
}

var aSubType = new  SubType("jack", 24)
aSubType.sayName()
// jack

var aSuperType = new SuperType("mack",35)
aSubType.job.push("softfore engineering")
console.log(aSuperType.job)
// ["teacher", "student", "softfore engineering"]
console.log(aSubType.job)
// ["teacher", "student", "softfore engineering"]

如下,我們大概了解了組合式繼承,但,正如星號(hào)(**)所標(biāo)記的那樣,組合繼承存在一個(gè)不足的地方,就是無論在何種情況下,都會(huì)調(diào)用兩次超類型構(gòu)函數(shù)。一次是在創(chuàng)建子類型原型的時(shí)候,一次是在子類型構(gòu)造函數(shù)內(nèi)部。

如何想解決這個(gè)問題,可以進(jìn)一步的使用寄生組合式繼承模式,它被認(rèn)為是引用類型最理想的繼承范式,也是實(shí)現(xiàn)基于類型繼承的最有效方式。

0x03 寄生組合式繼承

使用寄生組合式繼承可以不必為了指定子類型的原型而調(diào)用超類型的構(gòu)造函數(shù),我們所需要的無非是超類型的一個(gè)副本而已。

如下是寄生組合式繼承的基本模式:

function inheritPrototype(subType, superType){
    var prototype = Object(superType.prototype)             
    // 創(chuàng)建對象 
    prototype.constructor = subType;            
    // 增強(qiáng)對象
    subType.prototype = prototype;                
    // 指定對象
}

inheritPrototype() 函數(shù)接受兩個(gè)參數(shù):子類型構(gòu)造函數(shù)和超類型構(gòu)造函數(shù)。在函數(shù)中我們首先創(chuàng)建了一個(gè)超類型原型的一個(gè)副本,然后為創(chuàng)建的副本添加 constructor 屬性,從而彌補(bǔ)因重寫原型而失去的默認(rèn)的 constructor 屬性,最后我們將新創(chuàng)建的對象(原型副本)賦給子類型的原型。

如此,便可以使用 inheritPrototype() 函數(shù)替換組合式繼承模式中為子類原型賦值的操作了

function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","pink"];
}

SuperType.prototype = {
    // 重寫原型
    constructor: SuperType,
    // 將原型的構(gòu)造函數(shù)指向 SuperType
    job:["teacher","student"],
    sayName:function(){
        console.log(this.name)
    }
}

function SubType(name, age){
    
    SuperType.call(this, name); 
    this.age = age;
}

function inheritPrototype(subType, superType){
    var prototype = Object(superType.prototype) // 拷貝父級(jí)對象原型 
    prototype.constructor = subType;           //將子類原型構(gòu)造屬性指向其子類構(gòu)造函數(shù)
    subType.prototype = prototype;            // 指定對象
}

inheritPrototype(SubType, SuperType);

var aSubType = new  SubType("jack", 24)
aSubType.sayName()
// jack
console.log(aSubType.colors)
//["red", "blue", "pink"]

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86515.html

相關(guān)文章

  • 前端面試經(jīng)典題目匯總(持續(xù)更新中)

    摘要:只要沒有被覆蓋的話對象原型的屬性就能在所有的實(shí)例中找到,若整個(gè)原型鏈未找到則返回如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。 HTML相關(guān)問題 1.XHTML和HTML有什么區(qū)別 HTML是一種基本的WEB網(wǎng)頁設(shè)計(jì)語言,XHTML是一個(gè)基于XML的標(biāo)記語言最主要的不同:XHTML 元素必須被正確地嵌套。XHTML 元素必須被...

    BigNerdCoding 評(píng)論0 收藏0
  • 前端面試經(jīng)典題目匯總(持續(xù)更新中)

    摘要:只要沒有被覆蓋的話對象原型的屬性就能在所有的實(shí)例中找到,若整個(gè)原型鏈未找到則返回如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。 HTML相關(guān)問題 1.XHTML和HTML有什么區(qū)別 HTML是一種基本的WEB網(wǎng)頁設(shè)計(jì)語言,XHTML是一個(gè)基于XML的標(biāo)記語言最主要的不同:XHTML 元素必須被正確地嵌套。XHTML 元素必須被...

    Warren 評(píng)論0 收藏0
  • 前端面試經(jīng)典題目匯總(持續(xù)更新中)

    摘要:只要沒有被覆蓋的話對象原型的屬性就能在所有的實(shí)例中找到,若整個(gè)原型鏈未找到則返回如何實(shí)現(xiàn)繼承構(gòu)造繼承原型繼承實(shí)例繼承拷貝繼承原型機(jī)制或和方法去實(shí)現(xiàn)較簡單,建議使用構(gòu)造函數(shù)與原型混合方式。 HTML相關(guān)問題 1.XHTML和HTML有什么區(qū)別 HTML是一種基本的WEB網(wǎng)頁設(shè)計(jì)語言,XHTML是一個(gè)基于XML的標(biāo)記語言最主要的不同:XHTML 元素必須被正確地嵌套。XHTML 元素必須被...

    Tony_Zby 評(píng)論0 收藏0
  • JavaScript系列--淺析原型鏈繼承

    摘要:綜上所述有原型鏈繼承,構(gòu)造函數(shù)繼承經(jīng)典繼承,組合繼承,寄生繼承,寄生組合繼承五種方法,寄生組合式繼承,集寄生式繼承和組合繼承的優(yōu)點(diǎn)于一身是實(shí)現(xiàn)基于類型繼承的最有效方法。 一、前言 繼承是面向?qū)ο螅∣OP)語言中的一個(gè)最為人津津樂道的概念。許多面對對象(OOP)語言都支持兩種繼承方式::接口繼承 和 實(shí)現(xiàn)繼承 。 接口繼承只繼承方法簽名,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法。由于js中方法沒有簽名...

    draveness 評(píng)論0 收藏0
  • js繼承的理解

    摘要:創(chuàng)建自定義的構(gòu)造函數(shù)之后,其原型對象只會(huì)取得屬性,其他方法都是從繼承來的。優(yōu)缺點(diǎn)寄生式繼承在主要考慮對象而不是創(chuàng)建自定義類型和構(gòu)造函數(shù)時(shí),是十分有用的。 原文鏈接:https://kongchenglc.coding.me... 1.原型鏈 ??js的繼承機(jī)制不同于傳統(tǒng)的面向?qū)ο笳Z言,采用原型鏈實(shí)現(xiàn)繼承,基本思想是利用原型讓一個(gè)引用類型繼承另一個(gè)引用類型的屬性和方法。理解原型鏈必須先理...

    BlackFlagBin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<