你必須了解的JavaScript中的屬性描述對象詳解(上)
屬性描述對象
JavaScript其實支持多種編程范式的,包括函數(shù)式編程和面向?qū)ο缶幊蹋?/p>
- JavaScript沖的對象被設計為一組屬性無序集合,像是一個嘻哈表,由key和value組成;
- key是一個標識符名稱,value可以是任意類型,也可以是其他對象或者函數(shù)類型;
- 如果值是一個函數(shù),那么我們可以稱之為對象的方法。
所以,屬性描述對象的概念就為:JavaScript提供了一個內(nèi)部數(shù)據(jù)結構,用來描述對象的屬性,控制它的行為,比如該屬性是否可寫、可遍歷等等。這個內(nèi)部數(shù)據(jù)結構稱為“屬性描述對象”(attributes object)。每個屬性都有自己對應的屬性描述對象,保存該屬性的一些元信息。
下面是屬性描述對象的一個例子。
{ value:123, writable:false, enumerable:true, configurable:false, get:undefined, set:undefined }
屬性描述對象提供六個元屬性。
value
:value
是該屬性的屬性值,默認為undefined
。writable
:writable
是一個布爾值,表示屬性值(value)是否可改變(即是否可改寫),默認為true
。enumerable
:enumerable
是一個布爾值,表示該屬性是否可遍歷,默認為true
。如果設為false
,會使得某些操作(比如for...in
循環(huán)、Object.keys()
)跳過該屬性。configurable
:configurable
是一個布爾值,表示可配置性,默認為true
。如果設為false
,將阻止某些操作改寫屬性,比如無法刪除該屬性,也不得改變該屬性的屬性描述對象(value
屬性除外)。也就是說,configurable
屬性控制了屬性描述對象的可寫性。get
:get
是一個函數(shù),表示該屬性的取值函數(shù)(getter),默認為undefined
。set
:set
是一個函數(shù),表示該屬性的存值函數(shù)(setter),默認為undefined
。
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()
方法可以獲取屬性描述對象。他的第一個參數(shù)是目標對象,第二個參數(shù)是一個字符串,對應目標對象的某個屬性名。
var obj = (p:'a'}; Object.getOwnPropertyDescriptor(obj,'p') //Object{ value:"a", // writable:true, // enumerable:true, // configurable:true }
上面代碼中,Object.getOwnPropertyDescriptor()
方法獲取obj.p
的屬性描述對象。
注意,Object.getOwnPropertyDescriptor()
方法只能用于對象自身的屬性,不能用于繼承的屬性。
var obj = {p:'a'); Object.getOwnPropertyDescriptor(obj,'toStrng') //undefined
上面代碼中,toString
是obj
對象繼承的屬性,Object.getOwnPropertyDescriptor()
無法獲取。
Object.getOwnPropertyNames()
Object.getOwnPropertyNames
方法返回一個數(shù)組,成員是參數(shù)對象自身的全部屬性的屬性名,不管該屬性是否可遍歷。
var obj = Object.defineProperties({},{ p1:{value:1,enumerable:true}, p2:{value:2,enumerable:false} }); Object.getOwnPropertyNames(obj) //["p1","p2"]
上面代碼中,obj.p1
是可遍歷的,obj.p2
是不可遍歷的。Object.getOwnPropertyNames
會將它們都返回。
這跟Object.keys
的行為不同,Object.keys
只返回對象自身的可遍歷屬性的全部屬性名。
Object.keys([])//[] Object.getOwnPropertyNmaes([])//['length'] Object.keys(Object.prototype)// [] Object.getOwnPropertyNames(Object.prototype) //['hasOwmProperty' // 'valueOf', // 'constructor', // 'toLocaleString', // 'isPrototypeOf', // 'propertyIsEnumerable', // 'toString']
上面代碼中,數(shù)組自身的length
屬性是不可遍歷的,Object.keys
不會返回該屬性。第二個例子Object.prototype
也是一個對象,所有實例對象都會繼承它,它自身的屬性都是不可遍歷的。
Object.defineProperty(),Object.defineProperties()
Object.defineProperty()
方法允許通過屬性描述對象,定義或修改一個屬性,然后返回修改后的對象,它的用法如下。
Object.defineProperty(object,propertyName,attributesObject)
Object.defineProperty
方法接受三個參數(shù),依次如下。
- object:屬性所在的對象
- propertyName:字符串,表示屬性名
- attributesObject:屬性描述對象
舉例來說,定義obj.p
可以寫成下面這樣。
var obj = Object.defineProperty({},'p',{ value:123, writable:false, enumerable:true, configurable:false }); obj.p //123 obj.p = 246; obj.p //123
上面代碼中,Object.defineProperty()
方法定義了obj.p
屬性。由于屬性描述對象的writable
屬性為false
,所以obj.p
屬性不可寫。注意,這里的Object.defineProperty
方法的第一個參數(shù)是{}
(一個新建的空對象),p
屬性直接定義在這個空對象上面,然后返回這個對象,這是Object.defineProperty()
的常見用法。
如果屬性已經(jīng)存在,Object.defineProperty()
方法相當于更新該屬性的屬性描述對象。
如果一次性定義或修改多個屬性,可以使用Object.defineProperties()
方法。
var obj = Object.defineProperties({},{ p1:{value:123,enumerable:true}, p2:{value:'abc',enumerable:true}, p3:{get:function(){return this.p1 + this.p2}, enumerable:true, configurable:true } }); obj.p1 //123 obj.p2 //"abc" obj.p3 //"123abc"
上面代碼中,Object.defineProperties()
同時定義了obj
對象的三個屬性。其中,p3
屬性定義了取值函數(shù)get
,即每次讀取該屬性,都會調(diào)用這個取值函數(shù)。
注意,一旦定義了取值函數(shù)get
(或存值函數(shù)set
),就不能將writable
屬性設為true
,或者同時定義value
屬性,否則會報錯。
var obj = {}; Object.defineProperty(obj,'p',{ value:123, get:function(){return 456;} }); //TypeError: Invalid property. // A property cannot both have accessors and be writable or have a value Object.defineProperty(obj,'p'{ writable:true, get:function(){return 456;} }); // TypeError: Invalid property descriptor. // Cannot both specify accessors and a value or writable attribute
上面代碼中,同時定義了get
屬性和value
屬性,以及將writable
屬性設為true
,就會報錯。
Object.defineProperty()
和Object.defineProperties()
參數(shù)里面的屬性描述對象,writable
、configurable
、enumerable
這三個屬性的默認值都為false
。
var obj = {}; Object.defineProperty(obj,'foo',{}); Object.getOwnPropertyDescriptor(obj,'foo') //{ // value:undefined, // writable:false, // enumerable:false, // configurable:false //}
上面代碼中,定義obj.foo
時用了一個空的屬性描述對象,就可以看到各個元屬性的默認值。
Object.prototype.propertyIsEnumerable()
實例對象的propertyIsEnumerable()
方法返回一個布爾值,用來判斷某個屬性是否可遍歷。注意,這個方法只能用于判斷對象自身的屬性,對于繼承的屬性一律返回false
。
var obj = {}; obj.p = 123; obj.propertyIsEnumerable('p') //true obj.propertyIsEnumerable('toString') //false
上面代碼中,obj.p
是可遍歷的,而obj.toString
是繼承的屬性。
到此這篇關于你必須了解的JavaScript中的屬性描述對象詳解(上)的文章就介紹到這了,更多相關JavaScript屬性描述對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
javascript實現(xiàn)圖像循環(huán)明暗變化的方法
這篇文章主要介紹了javascript實現(xiàn)圖像循環(huán)明暗變化的方法,實例分析了javascript操作css樣式的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-02-02js實現(xiàn)瀑布流效果(自動生成新的內(nèi)容)
本文主要介紹了js實現(xiàn)瀑布流效果:當滾動條接近底部會自動生成新的內(nèi)容。具有很好的參考價值。下面跟著小編一起來看下吧2017-03-03谷歌瀏覽器不支持showModalDialog模態(tài)對話框的解決方法
谷歌瀏覽器不支持showModalDialog模態(tài)對話框和無法返回returnValue,這個問題,想必很多朋友都有遇到過吧,解決方法很簡單,下面的思路,大家可以看看2014-09-09詳解JavaScript調(diào)用棧、尾遞歸和手動優(yōu)化
本篇文章主要介紹了詳解JavaScript調(diào)用棧、尾遞歸和手動優(yōu)化,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06JavaScript判斷一個變量是否是數(shù)組的五種方式總結
在 JavaScript 編程中,我們經(jīng)常需要對不同類型的變量進行判斷和處理,其中,判斷一個變量是否是數(shù)組是一項基本且常見的任務,在本篇博客中,我們將介紹幾種常用的方式來判斷一個變量是否是數(shù)組,并探討它們的優(yōu)缺點以及適用場景,需要的朋友可以參考下2023-11-11JavaScript中的this指向綁定規(guī)則及常見面試總結
這篇文章主要為大家介紹了JavaScript中的this指向綁定規(guī)則及箭頭韓碩中的this指向,還b包含了常見面試總結,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-12-12