對象的屬性有兩種類型:字符串和 Symbol。javascript
var sybProp = Symbol()
var strProp = 'str'
var objProp = {}
var obj = {
[sybProp]: 'This is a String property',
[strProp]: 'This is a Symbol property',
[objProp]: 'This is also a String property'
}
obj
// {
// str: "This is a String property",
// [object Object]: "This is also a String property",
// Symbol(): "This is a Symbol property"
// }
複製代碼
由於對象只支持字符串和 Symbol 兩種類型的屬性,若是咱們使用的是任何其餘類型值做爲屬性名,最後都會被轉爲字符串。好比這裏的 [objProp]
,objProp
是個對象,用它建立完 obj
後,再看看,就變成字符串 "[object Object]"
了。java
爲了更好的演示,咱們先來定義一個操做對象。數據結構
var obj = {
str: 'This is a String property',
[Symbol()]: 'This is a Symbol property'
}
// 再定義一個不可枚舉屬性
Object.defineProperty(obj, 'unenum', {
value: 'This is a non-enumerable property',
writeable: true,
enumerable: false,
configurable: true
})
Object.defineProperty(obj, Symbol('unenum'), {
value: 'This is a non-enumerable Symbol property',
writeable: true,
enumerable: false,
configurable: true
})
//
Object.setPrototypeOf(obj, { foo: 'bar', [Symbol('foo')]: 'bar' })
複製代碼
這個對象覆蓋了下面要說的不一樣方法之間的區別。包括一個字符串屬性和 Symbol 屬性,同時還具備一個不可枚舉字符串屬性和 Symbol 屬性。另外,還重置了原型對象,原型對象裏包含了一個字符串屬性和 Symbol 屬性(都是可枚舉的)。ui
下面展現了 obj
的數據結構。spa
這三個方法都是用來獲取對象上的屬性集合的。只不過,Object.keys
是用來獲取屬性名集合,Object.values
是用來獲取屬性值集合,Object.entries
則是用來獲取屬性鍵-值對集合的。code
Object.keys(obj) // ["str"]
Object.values(obj) // ["This is a String property"]
Object.entries(obj) // [ ["str", "This is a String property"] ]
複製代碼
經過結果能夠發現,除了返回結果的不一樣以外,這三個屬性有一個共同點:只處理 obj
自身的可枚舉字符串屬性。cdn
顧名思義,Object.getOwnPropertyNames(obj)
獲取的是對象自身的屬性集合。但具體是哪些屬性呢?咱們看下:對象
Object.getOwnPropertyNames(obj) // ["str", "unenum"]
複製代碼
由結果可知,返回了 obj
自身的全部字符串屬性(包括不可枚舉的),但不包括 Symbol 屬性。blog
Object.getOwnPropertySymbols(obj)
是跟 Object.getOwnPropertyNames(obj)
相對應的,返回 obj
自身的全部 Symbol 屬性(包括不可枚舉的)。ip
Object.getOwnPropertySymbols(obj) // [Symbol(), Symbol(unenum)]
複製代碼
由結果可知,返回了 obj
自身的全部 Symbol 屬性(包括不可枚舉的),但不包括字符串屬性。
Reflect.ownKeys(obj)
能夠看作是 Object.getOwnPropertyNames(obj)
+ Object.getOwnPropertySymbols(obj)
,即得到 obj
自身的全部屬性集合。
Reflect.ownKeys(obj) // ["str", "unenum", Symbol(), Symbol(unenum)]
複製代碼
再來看看 for-in 語句遍歷對象的結果爲什麼。
for (let prop in obj) {
console.log(prop) // "str" -> "foo"
}
複製代碼
因而可知:for-in
返回的是對象自身及所在原型鏈上的全部可枚舉字符串屬性。
將 for-in 語句配合 obj.hasOwnProperty(prop)
方法一塊兒使用,就能獲得跟 Object.keys/values/entries
方法同樣的效果——即返回對象自身的可枚舉字符串屬性。
for (let prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log({ key: prop, value: obj[prop], pair: [prop, obj[prop]] })
}
}
// {key: "str", value: "This is a String property", pair: ["str", "This is a String property"] }
複製代碼
方法 | 返回值 | 備註 |
---|---|---|
Object.keys/values/entries |
對象自身的可枚舉字符串屬性 | |
Object.getOwnPropertyNames(obj) |
對象自身的全部可枚舉、不可枚舉的字符串屬性 | |
Object.getOwnPropertySymbols(obj) |
對象自身的全部可枚舉、不可枚舉的 Symbol 屬性 | |
Reflect.ownKeys(obj) |
對象自身的全部可枚舉、不可枚舉的字符串屬性、Symbol 屬性。 | 等同於 Object.getOwnPropertyNames(obj) + Object.getOwnPropertySymbols(obj) 的效果。 |
for (let prop in obj) {} |
對象自身及所在原型鏈上的全部可枚舉字符串屬性 |
(正文完)
廣告時間(長期有效)
我有一位好朋友開了一間貓舍,在此幫她宣傳一下。如今貓舍裏養的都是布偶貓。若是你也是個愛貓人士而且有須要的話,不妨掃一掃她的【閒魚】二維碼。不買也沒關係,看看也行。
(完)