003 理解對象

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

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

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

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

訪問器屬性

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

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

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

Object.defineProperty() 方法

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

  • 屬性所在的對象
  • 屬性名
  • 屬性描述符對象

調(diào)用該方法返回被定義后的對象。
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ù)中,我們訪問 name 屬性時返回當前對象的 _name 屬性,在 setter 函數(shù)中,我們設置 name 的值時會設置設置該對象的 _name 屬性,也就是 name 屬性的值始終依賴于 _name 屬性的值,而當我們修改 _name 屬性的值后,獲取到的 name 屬性的值也相應變化了。

關于 [[Configurable]] 描述符

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

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

此時會產(chǎn)生錯誤:

VM3119:1 Uncaught TypeError: Cannot redefine property: name

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

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

定義多個屬性

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

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

獲取屬性特性

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

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

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

Object.getOwnPropertyDescriptors(ball)

返回值:

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

完。

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

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

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

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