003 理解對(duì)象

在 JavaScript 中,每個(gè)對(duì)象都是基于另一個(gè)對(duì)象創(chuàng)建的,也叫做對(duì)象的原型。所有對(duì)象都是通過其原型對(duì)象創(chuàng)建出來的。
不同的對(duì)象都有各自的屬性,ECMAScript 中有兩種類型的屬性:數(shù)據(jù)屬性訪問器屬性。
數(shù)據(jù)屬性,就是最常見的有實(shí)實(shí)在在的值的屬性,訪問器屬性則是那些通過 gettersetter 函數(shù)進(jìn)行訪問和賦值的屬性。對(duì)于這兩種屬性,都有描述各自行為的特性。首先來看數(shù)據(jù)屬性。

數(shù)據(jù)屬性

數(shù)據(jù)屬性有以下幾個(gè)描述其行為的特性:

  • [[Configurable]]:此描述符表示是否能夠刪除該屬性,默認(rèn)為 true
  • [[Enumerable]]:此描述符表示該屬性是否可以通過 for-in 循環(huán)枚舉,默認(rèn)為 true
  • [[Writable]]:此描述符表示該屬性是否可寫,默認(rèn)為 true
  • [[Value]]:此描述符專門用來保存該屬性的值,讀取屬性時(shí),從這個(gè)位置讀取,寫入屬性時(shí)(如果該屬性可寫的情況下),就寫入在這個(gè)位置。該描述符的默認(rèn)值為 undefined。

訪問器屬性

訪問器屬性不包含具體的屬性值,其包含了一對(duì) gettersetter 函數(shù)(非必須),在讀取屬性值時(shí),將調(diào)用 getter 函數(shù),將此函數(shù)的返回值作為讀取的值。在設(shè)置屬性時(shí),將調(diào)用 setter 函數(shù),在該函數(shù)中完成對(duì)屬性值的設(shè)置。
訪問器屬性有以下幾個(gè)描述其行為的特性:

  • [[Configurable]]:同上
  • [[Enumerable]]:同上
  • [[Get]]:讀取屬性時(shí)調(diào)用的函數(shù),默認(rèn)值為 undefined
  • [[Set]]:設(shè)置屬性時(shí)調(diào)用的函數(shù),默認(rèn)值為 undefined

訪問器屬性不能直接定義,必須通過 Object.defineProperty() 來進(jìn)行定義。

Object.defineProperty() 方法

該方法用來對(duì)屬性進(jìn)行配置,包括數(shù)據(jù)屬性和訪問器屬性。該函數(shù)接受三個(gè)參數(shù):

  • 屬性所在的對(duì)象
  • 屬性名
  • 屬性描述符對(duì)象

調(diào)用該方法返回被定義后的對(duì)象。
1.定義數(shù)據(jù)屬性

let ball = {name:"basketball",brand:"NIKE"};
Object.defineProperty(ball,"name",{
    writable:false
}); //{name:"basketball",brand:"NIKE"}
ball.name = "pingpang";
ball.name //"basketball";

2.定義訪問器屬性

let ball = {}
Object.defineProperty(ball,"name",{
    get:function(){
        return this._name
    },
    set:function(name){
        this._name = name
    }
})
ball.name //undefined
ball.name = "籃球"
ball.name //"籃球"
ball._name //"籃球"
ball._name = "足球"
ball.name //"籃球"

getter 函數(shù)中,我們?cè)L問 name 屬性時(shí)返回當(dāng)前對(duì)象的 _name 屬性,在 setter 函數(shù)中,我們?cè)O(shè)置 name 的值時(shí)會(huì)設(shè)置設(shè)置該對(duì)象的 _name 屬性,也就是 name 屬性的值始終依賴于 _name 屬性的值,而當(dāng)我們修改 _name 屬性的值后,獲取到的 name 屬性的值也相應(yīng)變化了。

關(guān)于 [[Configurable]] 描述符

一旦將 [[Configurable]] 設(shè)置為 false 后,該屬性就變成了“不可配置”狀態(tài),此時(shí),除了對(duì) [[Writable]] 描述符進(jìn)行配置外,進(jìn)行其他的配置都會(huì)報(bào)錯(cuò)。

let ball = {}
Object.defineProperty(ball,"name",{
    configurable:false,
    value:"籃球"
})
// 再次配置
Object.defineProperty(ball,"name",{
    configurable:true,
})

此時(shí)會(huì)產(chǎn)生錯(cuò)誤:

VM3119:1 Uncaught TypeError: Cannot redefine property: name

但是我們?nèi)匀豢梢詫?duì) [[Writable]] 描述符進(jìn)行配置:

Object.defineProperty(ball,"name",{
    writable:false,
})
ball.name = "足球"
ball.name //"籃球"

定義多個(gè)屬性

ES5 還提供了定義多個(gè)屬性的方法:Object.defineProperties(),該方法接受兩個(gè)參數(shù),第一個(gè)參數(shù)是配置屬性的對(duì)象,第二個(gè)參數(shù)是一個(gè)針對(duì)待配置屬性的描述字典:

let ball = {}
Object.defineProperties(ball,{
    name:{
        writable:false
    },
    brand:{
        configurable:false
    }
})

獲取屬性特性

通過 Object.getOwnPropertyDescriptor() 方法,可以獲取對(duì)象的屬性的描述符。該方法接受兩個(gè)參數(shù):屬性所在的對(duì)象和屬性名。

let ball = {}
Object.defineProperties(ball,{
    name:{
        writable:false
    },
    brand:{
        configurable:false
    }
})
Object.getOwnPropertyDescriptor(ball,"name") //{value: undefined, writable: false, enumerable: false, configurable: false}

另外,還有一個(gè) Object.getOwnPropertyDescriptors()方法,可以獲取對(duì)象上所有的屬性特性,該方法只接受一個(gè)對(duì)象作為參數(shù),返回該對(duì)象所有的屬性描述符:

Object.getOwnPropertyDescriptors(ball)

返回值:

{
brand: {value: undefined, writable: false, enumerable: false, configurable: false},
name: {value: undefined, writable: false, enumerable: false, configurable: false}
}

完。

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,502評(píng)論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,297評(píng)論 6 13
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,527評(píng)論 3 12
  • 《牧羊少年的奇幻之旅》隨想二 1 你敢做自己么? 這個(gè)世界上我們有太多的不敢,不敢違抗父母,不敢違抗權(quán)威,更多的是...
    阿柒柒成長記閱讀 632評(píng)論 0 2
  • 從前有一個(gè)偏遠(yuǎn)的村莊,村莊的不遠(yuǎn)處有一個(gè)山洞。村莊里流傳著一個(gè)關(guān)于山洞的古老的傳說,傳說中說道:“山洞里居住著一個(gè)...
    海王星1984閱讀 363評(píng)論 0 1

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