javascript遍歷對象的幾種方法


總結下在JavaScript中遍歷對象的幾種方法。

for in

for in循環是最基礎的遍歷對象的方式,除了能拿到到對象自身的屬性之外,它還能拿到對象原型鏈上的屬性。

// 創建一個對象並指定其原型,yanggb為原型上的屬性
const obj = Object.create({
 yanggb: 'yanggb'
})
 
// yanggb1為對象自身的屬性
obj.yanggb1 = 'yanggb1'
 
for (let key in obj) {
 console.log(obj[key]) // yanggb1, yanggb
}

可以看到對象原型上的屬性也被循環出來了,首先是遍歷了自身的屬性,然后逐層往上遍歷原型鏈上原型的屬性。

如果想要過濾掉原型鏈上的屬性,也可以使用對象的hasOwnProperty()方法判斷其是否是自身屬性,以此來達到只針對自身的屬性做相應操作的目的。

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

這時候原型上的yanggb屬性就被過濾掉了。

Object.keys

Object.keys()是ES5新增的一個對象方法,該方法返回對象自身屬性名組成的數組,它會自動過濾掉原型鏈上的屬性,然后可以通過數組的forEach()方法來遍歷。

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

此外還有Object.values()方法和Object.entries()方法,這兩方法的作用范圍和Object.keys()方法類似,分別是取得對象的屬性值數組和屬性鍵值數組數組。

for in循環和Object.keys()方法一樣,都不會返回對象的不可枚舉屬性,如果需要遍歷不可枚舉的屬性,就要使用Object.getOwnPropertyNames()方法了。

Object.getOwnPropertyNames

Object.getOwnPropertyNames()同樣也是ES5新增的一個對象方法,該方法會返回對象自身屬性名組成的數組,包括不可枚舉的屬性,因此也可以通過數組的forEach()方法來遍歷。

// 創建一個對象並指定其原型,yanggb為原型上的屬性
// yanggb1為對象自身的屬性並且不可枚舉
const obj = Object.create({
 yanggb: 'yanggb'
}, {
 yanggb1: {
  value: 'yanggb1',
  enumerable: false
 }
})
 
obj.yanggb2 = 'yanggb2'
 
// 不包括不可枚舉的yanggb1屬性
Object.keys(obj).forEach((key) => {
 console.log(obj[key]) // yanggb1
})
 
// 包括不可枚舉的yanggb1屬性
Object.getOwnPropertyNames(obj).forEach((key) => {
 console.log(obj[key]) // yanggb1,yanggb2
})

而在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('yanggb')]: {
  value: 'Symbol yanggb',
  enumerable: false
 }
})
 
// 給對象添加一個可枚舉的Symbol屬性
obj[Symbol('yanggb1')] = 'Symbol yanggb1'
 
Object.getOwnPropertySymbols(obj).forEach((key) => {
 console.log(obj[key]) // Symbol yanggb, Symbol yanggb1
})

這時候就會輸出所有的Symbol屬性,包括可枚舉不可枚舉Symbol屬性。

Reflect.ownKeys

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

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

既然方法有那么多,自然需要對比一下才能知道不同的場景該怎么選用。

幾種方法的對比

通過一個表格直觀得對比:

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

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

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

 

"成長的經歷,大概能讓人變得越來越安靜。"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM