判断属性存在或者遍历属性是平常开发中常常会用到。只是针对这些操做符、语句、方法,有些混淆。因此总结一下。javascript
对象属性目前只能是字符串值或者 symbol 值html
A property key value is either an ECMAScript String value or a Symbol valuejava
明确了这个规则后,开始下面的说明。web
翻译为属性的属性?这个概念我也有点说不清,看看下面的参考数组
Property Attributes
有 Value、Writable、Enumerable、Configurable。这个能够经过 Object.getOwnPropertyDescriptor
获取值。经过 Object.defineProperty
进行定义或者修改。oop
另外还有 Get、Setthis
本文的重点是讨论 Enumerable
,这个值设置为 false 后,属性是不可遍历的。spa
可是不可遍历了,我仍是须要获取这个属性该怎么办?
指定的属性在指定的对象或其原型链中,则in 运算符返回true
Reflect.has
和 in
的效果相同
这里的重点是 in
会检查原型链
console.log(length in []); // true // 继承的 Symbol console.log(Symbol.iterator in []); // true // 继承的方法 console.log('toString' in []); // true 复制代码
for...in
循环只遍历可枚举属性(包括它的原型链上的可枚举属性)
所以 for...in
的行为受到 Enumerable
的控制
for in 区别 // 遍历除了 symbol 之外的可枚举
属性
let obj = { [Symbol('my_key')]: 1, enum: 2, nonEnum: 3 }; Object.defineProperty(obj, 'nonEnum', { enumerable: false }); console.log(Object.keys(obj)) let obj2 = Object.create(obj) obj2.myVal = 5 console.log(obj2); // { myVal: 5 } for (var prop in obj2) { console.log('obj2 prop: ', prop); // myVal, enum } 复制代码
会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用 for...in 循环遍历该对象时返回的顺序一致 。
// 省略上面的代码 Object.keys(obj) // ['enum'] Object.keys(obj2) // ['myVal'] 复制代码
返回一个由指定对象的全部自身属性的属性名(包括不可枚举属性但不包括Symbol值做为名称的属性)组成的数组。
// 省略上面的代码 Object.getOwnPropertyNames(obj) // ['enum', 'nonEnum'] 复制代码
Object.prototype.hasOwnProperty
用来判断对象自身属性。
一个经常使用的判断:遍历一个对象的全部自身属性
var buz = { fog: 'stack' }; for (var name in buz) { if (buz.hasOwnProperty(name)) { console.log('this is fog (' + name + ') for sure. Value: ' + buz[name]); } else { console.log(name); // toString or something else } } 复制代码
返回一个给定对象自身的全部 Symbol 属性的数组
// 省略上面的代码 Object.getOwnPropertySymbols(obj) // [ Symbol(my_key) ] 复制代码
上面的方法操做符,饶了一圈。和 Enumerable
Symbol
的有无打交道。
有没有方法可以拿到全部的属性 (我全都要.webp)
答案就是: Reflect.ownKeys
// 省略上面的代码 Reflect.ownKeys(obj) // [ Symbol(my_key), 'enum', 'nonEnum' ] 复制代码
对象属性目前只能是字符串值或者 symbol 值。因此下面的状况会出现 toPrimitive
或者 toString
的转换
let obj3 = { [obj]: 33 } // { '[object Object]': 33 } 复制代码
固然须要使用对象做为 key, 须要用到 Map
了,这些是后话。
通常状况下都是用 Object.keys
来遍历自身可枚举属性。Object.keys
是 ES5 的标准。
之前 ES3 的时候是须要 in
操做符 和 hasOwnProperty
配合使用
全都要的状况: Reflect.ownKeys
要考虑 Enumerable
为 false 时, 用 Object.getOwnPropertyNames
要考虑 Symbol
时, 用 Object.getOwnPropertySymbols
in - JavaScript | MDN Keys in Javascript objects can only be strings? - Stack Overflow