几天前一个小伙伴问我 Object.getOwnPropertyNames() 是干什么用的 Object.getOwnPropertyNames() 平时还真没有使用到这个方法,一时不知如何回答从方法名称来分析,应该是返回的是对象自身属性名组成的数组那和 Object.keys() 方法不就一样了吗Object.keys() 感觉事情并不这么简单,于是我仔细看了一下这几种遍历对象的方法的区别for infor infor in 循环是最基础的遍历对象的方式,它还会得到对象原型链上的属性
// 创建一个对象并指定其原型,bar 为原型上的属性
const obj = Object.create({
bar: 'bar'
})

// foo 为对象自身的属性
obj.foo = 'foo'

for (let key in obj) {
console.log(obj[key]) // foo, bar
}
// 创建一个对象并指定其原型,bar 为原型上的属性
const obj = Object.create({
bar: 'bar'
})

// foo 为对象自身的属性
obj.foo = 'foo'

for (let key in obj) {
console.log(obj[key]) // foo, bar
}可以看到对象原型上的属性也被循环出来了在这种情况下可以使用对象的 hasOwnProperty() 方法过滤掉原型链上的属性hasOwnProperty()
for (let key in obj) {
if (obj.hasOwnProperty(key)) {

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

console.log(obj[key]) // foo
}
}这时候原型上的 bar 属性就被过滤掉了Object.keysObject.keysObject.keys() 是 ES5 新增的一个对象方法,该方法返回对象自身属性名组成的数组,它会自动过滤掉原型链上的属性,然后可以通过数组的 forEach() 方法来遍历Object.keys()forEach()
Object.keys(obj).forEach((key) => {
console.log(obj[key]) // foo
})
Object.keys(obj).forEach((key) => {
console.log(obj[key]) // foo
})另外还有 Object.values() 方法和 Object.entries() 方法,这两方法的作用范围和 Object.keys() 方法类似,因此不再说明 Object.values()
Object.entries() Object.keys() for in 循环和 Object.keys() 方法都不会返回对象的不可枚举属性Object.keys() 如果需要遍历不可枚举的属性,就要用到前面提到的 Object.getOwnPropertyNames() 方法了 Object.getOwnPropertyNames() Object.getOwnPropertyNames
Object.getOwnPropertyNames
Object.getOwnPropertyNames() 也是 ES5 新增的一个对象方法,该方法返回对象自身属性名组成的数组,包括不可枚举的属性,也可以通过数组的 forEach 方法来遍历Object.getOwnPropertyNames() 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
})
// 创建一个对象并指定其原型,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
})ES2021 新增了 Symbol 数据类型,该类型可以作为对象的键,针对该类型 ES2021 同样新增Object.getOwnPropertySymbols() 方法Object.getOwnPropertySymbols() Object.getOwnPropertySymbols
Object.getOwnPropertySymbols
Object.getOwnPropertySymbols() 方法返回对象自身的 Symbol 属性组成的数组,不包括字符串属性Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols(obj).forEach((key) => {
console.log(obj[key])
})
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
})
// 给对象添加一个不可枚举的 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.ownKeysReflect.ownKeysReflect.ownKeys() 方法是 ES2021 新增的静态方法,该方法返回对象自身所有属性名组成的数组,包括不可枚举的属性和 Symbol 属性Reflect.ownKeys()
Reflect.ownKeys(obj).forEach((key) => {
console.log(obj[key]) // baz, foo, Symbol baz, Symbol foo
})
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()


















方式

基本属性

原型链

不可枚举

Symbol





for in













Object.keys()













Object.getOwnPropertyNames()













Object.getOwnPropertySymbols()













Reflect.ownKeys()













方式

基本属性

原型链

不可枚举

Symbol

方式方式基本属性基本属性原型链原型链不可枚举不可枚举SymbolSymbol

for in









for in是是否否

Object.keys()









Object.keys()是否否否

Object.getOwnPropertyNames()









Object.getOwnPropertyNames()是否是否

Object.getOwnPropertySymbols()









Object.getOwnPropertySymbols()否否是是

Reflect.ownKeys()









Reflect.ownKeys()是否是是结论结论这其中只有 for in 循环会得到对象原型链上的属性,其它方法都只适用于对象自身的属性ES 语言后续添加的新特性不会对以前的代码产生副作用,比如在 ES2021 之前就存在的 for in 循环,Object.keys() 和 Object.getOwnPropertyNames() 是肯定不会返回 Symbol 属性的以上就是JS 5种遍历对象的方式的详细内容,关于JS 遍历对象的资料请关注其它相关文章!