JS遍歷對象的幾種方法

幾天前一個小夥伴問我 Object.getOwnPropertyNames() 是幹什麼用的數組

平時還真沒有使用到這個方法,一時不知如何回答code

從方法名稱來分析,應該是返回的是對象自身屬性名組成的數組對象

那和 Object.keys() 方法不就同樣了嗎原型鏈

感受事情並不這麼簡單,因而我仔細看了一下這幾種遍歷對象的方法的區別字符串

for in

for in 循環是最基礎的遍歷對象的方式,它還會獲得對象原型鏈上的屬性get

// 建立一個對象並指定其原型,bar 爲原型上的屬性
const obj = Object.create({
  bar: 'bar'
})

// foo 爲對象自身的屬性
obj.foo = 'foo'

for (let key in obj) {
  console.log(obj[key]) // foo, bar
}

能夠看到對象原型上的屬性也被循環出來了原型

在這種狀況下可使用對象的 hasOwnProperty() 方法過濾掉原型鏈上的屬性console

for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(obj[key]) // foo
  }
}

這時候原型上的 bar 屬性就被過濾掉了table

Object.keys

Object.keys() 是 ES5 新增的一個對象方法,該方法返回對象自身屬性名組成的數組,它會自動過濾掉原型鏈上的屬性,而後能夠經過數組的 forEach() 方法來遍歷class

Object.keys(obj).forEach((key) => {
  console.log(obj[key]) // foo
})

另外還有 Object.values() 方法和 Object.entries() 方法,這兩方法的做用範圍和 Object.keys() 方法相似,所以再也不說明

for in 循環和 Object.keys() 方法都不會返回對象的不可枚舉屬性

若是須要遍歷不可枚舉的屬性,就要用到前面提到的 Object.getOwnPropertyNames() 方法了

Object.getOwnPropertyNames

Object.getOwnPropertyNames() 也是 ES5 新增的一個對象方法,該方法返回對象自身屬性名組成的數組,包括不可枚舉的屬性,也能夠經過數組的 forEach 方法來遍歷

// 建立一個對象並指定其原型,bar 爲原型上的屬性
// baz 爲對象自身的屬性而且不可枚舉
const obj = Object.create({
  bar: 'bar'
}, {
  baz: {
    value: 'baz',
    enumerable: false
  }
})

obj.foo = 'foo'

// 不包括不可枚舉的 baz 屬性
Object.keys(obj).forEach((key) => {
  console.log(obj[key]) // foo
})

// 包括不可枚舉的 baz 屬性
Object.getOwnPropertyNames(obj).forEach((key) => {
  console.log(obj[key]) // baz, foo
})

ES2015 新增了 Symbol 數據類型,該類型能夠做爲對象的鍵,針對該類型 ES2015 一樣新增了 Object.getOwnPropertySymbols() 方法

Object.getOwnPropertySymbols

Object.getOwnPropertySymbols() 方法返回對象自身的 Symbol 屬性組成的數組,不包括字符串屬性

Object.getOwnPropertySymbols(obj).forEach((key) => {
  console.log(obj[key])
})

什麼都沒有,由於該對象尚未 Symbol 屬性

// 給對象添加一個不可枚舉的 Symbol 屬性
Object.defineProperties(obj, {
  [Symbol('baz')]: {
    value: 'Symbol baz',
    enumerable: false
  }
})

// 給對象添加一個可枚舉的 Symbol 屬性
obj[Symbol('foo')] = 'Symbol foo'

Object.getOwnPropertySymbols(obj).forEach((key) => {
  console.log(obj[key]) // Symbol baz, Symbol foo
})

Reflect.ownKeys

Reflect.ownKeys() 方法是 ES2015 新增的靜態方法,該方法返回對象自身全部屬性名組成的數組,包括不可枚舉的屬性和 Symbol 屬性

Reflect.ownKeys(obj).forEach((key) => {
  console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo
})

對比

方式 基本屬性 原型鏈 不可枚舉 Symbol
for in
Object.keys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Reflect.ownKeys()

結論

這其中只有 for in 循環會獲得對象原型鏈上的屬性,其它方法都只適用於對象自身的屬性

ES 語言後續添加的新特性不會對之前的代碼產生反作用,好比在 ES2015 以前就存在的 for in 循環,Object.keys() 和 Object.getOwnPropertyNames() 是確定不會返回 Symbol 屬性的

相關文章
相關標籤/搜索