是八股文,但也是基础!js 中有关对象属性的判断与遍历!

内容整理自:Enumerability and ownership of properties - JavaScript | MDN (mozilla.org)

枚举性:

  • 字面量创建对象属性时,默认是可枚举的。
  • 使用 Object.defineProperty 创建属性时,默认是不可枚举的。

js 中有四种方式可以判断某个属性是否存在该对象身上。下面表格对其进行了归纳和总结。

  • ✅ 表示能判断这种属性是否存在
  • ❌ 表示无法判断这种属性是否存在。即:始终返回 false
自身、可枚举属性自身、不可枚举属性自身、symbol 属性继承、可枚举属性继承、不可枚举属性继承、symbol 属性
in
Object.hasOwn()
hasOwnProperty()
propertyIsEnumerable()

下面表格总结了 js 中可以遍历对象属性的方式,以及这种方式能否访问到某类属性。

  • ✅ (strings) 表示只有当该属性是 string 类型时才能访问到。
  • ✅ (symbols) 表示只有当该属性是 symbol 类型时才能访问到。
  • ❌表示访问不到。
自身、可枚举的属性自身、不可枚举属性自身、symbol 属性继承、可枚举属性继承、不可枚举属性继承、symbol 属性
Object.keys Object.values Object.entries✅ (strings)
Object.getOwnPropertyNames✅ (strings)✅ (strings)
Object.getOwnPropertySymbols✅ (symbols)
Object.getOwnPropertyDescriptors✅ (strings)✅ (symbols)
Reflect.ownKeys✅ (strings)✅ (symbols)
for…in✅ (strings)✅ (strings)

此外,还有一些其他方法,也涉及到属性

自身、可枚举的属性自身、不可枚举属性自身、symbol 属性继承、可枚举属性继承、不可枚举属性继承、symbol 属性
Object.assign 其中的 sourceN 参数✅ (strings)✅ (symbols)
展开运算符 …✅ (strings)✅ (symbols)

下面是测试代码:

const inheritSymbol = Symbol('继承 symbol 属性')
const ownSymbol = Symbol('自身 symbol 属性')
const parent = {
    '继承可枚举属性': 0,
    [inheritSymbol]: 0
}
Object.defineProperty(parent, '继承不可枚举属性', {})
const obj = Object.create(parent)
obj['自身可枚举属性'] = 0
Object.defineProperty(obj, '自身不可枚举属性', {})
obj[ownSymbol] = 0

console.log('\nin')
console.log('自身可枚举属性' in obj, ' \t自身可枚举属性')
console.log('自身不可枚举属性' in obj, ' \t自身不可枚举属性')
console.log(ownSymbol in obj, ' \townSymbol')
console.log('继承可枚举属性' in obj, ' \t继承可枚举属性')
console.log('继承不可枚举属性' in obj, ' \t继承不可枚举属性')
console.log(inheritSymbol in obj, ' \tinheritSymbol')

console.log('\nObject.hasOwn')
console.log(Object.hasOwn(obj, '自身可枚举属性'), ' \t自身可枚举属性')
console.log(Object.hasOwn(obj, '自身不可枚举属性'), ' \t自身不可枚举属性')
console.log(Object.hasOwn(obj, ownSymbol), ' \townSymbol')
console.log(Object.hasOwn(obj, '继承可枚举属性'), ' \t继承可枚举属性')
console.log(Object.hasOwn(obj, '继承不可枚举属性'), ' \t继承不可枚举属性')
console.log(Object.hasOwn(obj, inheritSymbol), ' \tinheritSymbol')

console.log('\nhasOwnProperty')
console.log(obj.hasOwnProperty('自身可枚举属性'), ' \t自身可枚举属性')
console.log(obj.hasOwnProperty('自身不可枚举属性'), ' \t自身不可枚举属性')
console.log(obj.hasOwnProperty(ownSymbol), ' \townSymbol')
console.log(obj.hasOwnProperty('继承可枚举属性'), ' \t继承可枚举属性')
console.log(obj.hasOwnProperty('继承不可枚举属性'), ' \t继承不可枚举属性')
console.log(obj.hasOwnProperty(inheritSymbol), ' \tinheritSymbol')

console.log('\npropertyIsEnumerable')
console.log(obj.propertyIsEnumerable('自身可枚举属性'), ' \t自身可枚举属性')
console.log(obj.propertyIsEnumerable('自身不可枚举属性'), ' \t自身不可枚举属性')
console.log(obj.propertyIsEnumerable(ownSymbol), ' \townSymbol')
console.log(obj.propertyIsEnumerable('继承可枚举属性'), ' \t继承可枚举属性')
console.log(obj.propertyIsEnumerable('继承不可枚举属性'), ' \t继承不可枚举属性')
console.log(obj.propertyIsEnumerable(inheritSymbol), ' \tinheritSymbol')

console.log('\nObject.keys')
console.log(Object.keys(obj))

console.log('\nObject.getOwnPropertyNames')
console.log(Object.getOwnPropertyNames(obj))

console.log('\nObject.getOwnPropertySymbols')
console.log(Object.getOwnPropertySymbols(obj))

console.log('\nObject.getOwnPropertyDescriptors')
console.log(Object.getOwnPropertyDescriptors(obj))

console.log('\nReflect.ownKeys')
console.log(Reflect.ownKeys(obj))

console.log('\nfor...in')
for (const key in obj) { console.log(key) }

console.log('\nObject.assign')
console.log('自身可枚举属性' in Object.assign({}, obj), ' \t自身可枚举属性')
console.log('自身不可枚举属性' in Object.assign({}, obj), ' \t自身不可枚举属性')
console.log(ownSymbol in Object.assign({}, obj), ' \townSymbol')
console.log('继承可枚举属性' in Object.assign({}, obj), ' \t继承可枚举属性')
console.log('继承不可枚举属性' in Object.assign({}, obj), ' \t继承不可枚举属性')
console.log(inheritSymbol in Object.assign({}, obj), ' \tinheritSymbol')

console.log('\nObject spread ...')
console.log('自身可枚举属性' in {...obj}, ' \t自身可枚举属性')
console.log('自身不可枚举属性' in {...obj}, ' \t自身不可枚举属性')
console.log(ownSymbol in {...obj}, ' \townSymbol')
console.log('继承可枚举属性' in {...obj}, ' \t继承可枚举属性')
console.log('继承不可枚举属性' in {...obj}, ' \t继承不可枚举属性')
console.log(inheritSymbol in {...obj}, ' \tinheritSymbol')

  • 11
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值