對(duì)象/原型/繼承

對(duì)象屬性

一、屬性類型
ECMAScript 中有數(shù)據(jù)屬性訪問(wèn)器屬性兩種屬性,各有 4 個(gè)描述其行為的特征,其中兩種屬性都有的特性是:

  • [[configurable]] 默認(rèn)為 true,能否刪除屬性、修改屬性特征、修改屬性類型
  • [[enumerable]] 默認(rèn)為 true,是否可枚舉,即被 for-in 循環(huán)、Object.keys 等遍歷到

數(shù)據(jù)屬性 同時(shí)可具有:

  • [[value]] 默認(rèn)為 undefined,數(shù)據(jù)值
  • [[writable]] 默認(rèn)為 true,能否修改屬性的值

訪問(wèn)器屬性同時(shí)可具有:

  • [[get]] 默認(rèn)為 undefined,讀取屬性時(shí)調(diào)用的 getter 函數(shù)
  • [[set]] 默認(rèn)為 undefined,讀取屬性時(shí)調(diào)用的 setter 函數(shù)

需要注意的是,數(shù)據(jù)屬性訪問(wèn)器屬性不能同時(shí)存在
可以是用 Object.defineProperty或者Object.defineProperties來(lái)修改對(duì)象的屬性,在使用這兩個(gè)函數(shù)的時(shí)候,如果不指定,configurable、enumerablewritable的默認(rèn)值都為 false

原型

實(shí)例.__proto__ === 原型
原型.constructor === 構(gòu)造函數(shù)
構(gòu)造函數(shù).prototype === 原型

原型鏈

每個(gè)對(duì)象都有 __proto__ 屬性,指向了創(chuàng)建該對(duì)象的構(gòu)造函數(shù)的原型,__proto__將對(duì)象連接起來(lái)組成了原型鏈,原型鏈可以用于實(shí)現(xiàn)繼承共享屬性

繼承

一、原型鏈繼承

  • 優(yōu)點(diǎn):簡(jiǎn)單
  • 缺點(diǎn):多個(gè)實(shí)例共享引用類型的屬性
    function Parent(age) {
        this.names = []
        this.age = age
    }

    Parent.prototype.foo = () => {}
    function Child() {}

    Child.prototype = new Parent()
    var child1 = new Child(5)
    var child2 = new Child(6)
    child1.names.push(1)
    child2.names.push(2)

二、構(gòu)造函數(shù)

  • 優(yōu)點(diǎn):
    1.不共享引用類型的屬性
    2.可傳參
  • 缺點(diǎn):
    1.每次創(chuàng)建實(shí)例都會(huì)重新創(chuàng)建一遍方法,函數(shù)沒(méi)有復(fù)用
    2.不屬于原型鏈的一環(huán),子類實(shí)例不能使用父類的方法
    function Parent(age) {
        this.names = []
        this.age = age
        this.foo = function () {}
    }

    function Child(age) {
        Parent.call(this, age)
    }

    var child = new Child(11)

三、組合繼承

  • 優(yōu)點(diǎn):
    1.原型鏈確保了函數(shù)復(fù)用
    2.構(gòu)造函數(shù)實(shí)現(xiàn)了對(duì)實(shí)例屬性的繼承
  • 缺點(diǎn):
    1.調(diào)用了兩次父類構(gòu)造函數(shù)
    function Parent(age) {
        this.name = 'Bill'
        this.age = age
    }
    Parent.prototype.foo = function () {}

    function Child(age) {
        Parent.call(this, age) //第二次調(diào)用構(gòu)造函數(shù)
    }

    Child.prototype = new Parent() //第一次調(diào)用構(gòu)造函數(shù)
    Child.prototype.constructor = Child
    var child = new Child(11)

四、原型式繼承
與原型鏈類似

  • 優(yōu)點(diǎn):簡(jiǎn)單
  • 缺點(diǎn):多個(gè)實(shí)例共享引用類型的屬性
const objectCreate = (o) => {
    // 就是Object.create 靜態(tài)方法的實(shí)現(xiàn)
    // 實(shí)際上只是對(duì) o 進(jìn)行了淺拷貝
    function F() {}
    F.prototype = o
    return new F()
}

五、寄生式繼承
與借用構(gòu)造函數(shù)類似

  • 缺點(diǎn):每次創(chuàng)建實(shí)例都會(huì)重新創(chuàng)建一遍方法,函數(shù)沒(méi)有復(fù)用
    function create(o) {
        var f = Object.create(o)
        f.foo = function() {}
        return f
    }

六、寄生組合式繼承
主要是改進(jìn)了組合繼承需要調(diào)用兩次構(gòu)造函數(shù)的缺點(diǎn)

function object(o) {
    function F() {}
    F.prototype = o
    return new F()
}

// 這里代替了用來(lái) 組合式繼承 第一次調(diào)用構(gòu)造函數(shù)
// 將父類的原型進(jìn)行一次淺拷貝
// 并將這個(gè)淺拷貝的對(duì)像作為原型鏈接到子類
function inheritPrototype(subType, superType) {
    var prototype = object(superType.prototype)
    prototype.constructor = subType
    subType.prototype = prototype
}

function SuperType(name) {
    this.name = name
    this.colors = ['red', 'blue']
}
SuperType.prototype.sayName = function() {
    alert(this.name)
}

function SubType(name, age) {
    SuperType.call(this, name)
    this.age = age
}
SubType.prototype.sayAge = function() {
    alert(this.age)
}

inheritPrototype(SubType, SuperType)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,537評(píng)論 3 12
  • (注1:如果有問(wèn)題歡迎留言探討,一起學(xué)習(xí)!轉(zhuǎn)載請(qǐng)注明出處,喜歡可以點(diǎn)個(gè)贊哦?。ㄗ?:更多內(nèi)容請(qǐng)查看我的目錄。) ...
    love丁酥酥閱讀 1,431評(píng)論 4 8
  • 1.繼承(接口繼承和實(shí)現(xiàn)繼承) 繼承是 OO 語(yǔ)言中的一個(gè)最為人津津樂(lè)道的概念。許多 OO 語(yǔ)言都支持兩種繼承方式...
    believedream閱讀 1,061評(píng)論 0 3
  • 繼承是 OO 語(yǔ)言中的一個(gè)最為人津津樂(lè)道的概念。許多 OO 語(yǔ)言都支持兩種繼承方式:接口繼承 和 實(shí)現(xiàn)繼承。接口繼...
    threetowns閱讀 491評(píng)論 0 0
  • 繼承的概念:子類可以使用父類共享的屬性和方法,避免重復(fù)代碼提高代碼復(fù)用性。 原型鏈:子類可以共享父類的實(shí)例對(duì)象和實(shí)...
    淺秋_6672閱讀 462評(píng)論 0 0

友情鏈接更多精彩內(nèi)容