JS:獲取對象屬性有哪些方法?

對象的兩類屬性

對象的屬性有兩種類型:字符串和 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

image.png

Object.keys/values/entries

這三個方法都是用來獲取對象上的屬性集合的。只不過,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) 獲取的是對象自身的屬性集合。但具體是哪些屬性呢?咱們看下:對象

Object.getOwnPropertyNames(obj) // ["str", "unenum"]
複製代碼

由結果可知,返回了 obj 自身的全部字符串屬性(包括不可枚舉的),但不包括 Symbol 屬性。blog

Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols(obj) 是跟 Object.getOwnPropertyNames(obj) 相對應的,返回 obj 自身的全部 Symbol 屬性(包括不可枚舉的)ip

Object.getOwnPropertySymbols(obj) // [Symbol(), Symbol(unenum)]
複製代碼

由結果可知,返回了 obj 自身的全部 Symbol 屬性(包括不可枚舉的),但不包括字符串屬性。

Reflect.ownKeys(obj)

Reflect.ownKeys(obj) 能夠看作是 Object.getOwnPropertyNames(obj) + Object.getOwnPropertySymbols(obj),即得到 obj 自身的全部屬性集合

Reflect.ownKeys(obj) // ["str", "unenum", Symbol(), Symbol(unenum)]
複製代碼

for-in

再來看看 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) {} 對象自身及所在原型鏈上的全部可枚舉字符串屬性

(正文完)


廣告時間(長期有效)

我有一位好朋友開了一間貓舍,在此幫她宣傳一下。如今貓舍裏養的都是布偶貓。若是你也是個愛貓人士而且有須要的話,不妨掃一掃她的【閒魚】二維碼。不買也沒關係,看看也行。

(完)

相關文章
相關標籤/搜索