CODE
const proto = {
type: 'human',
[Symbol('p')]: 'created'
}
const person = Object.create(proto, {
name: {
value: 'zhangsan',
enumerable: true,
writable: true,
configurable: true
},
sex: {
enumerable: false,
configurable: true,
writable: true,
value: 1
}
})
person[Symbol('id')] = 1
Reflect.setPrototypeOf(person, proto)
for (let k in person) {
console.log(k)
}
console.log('-------------------------in关键字----------------------------')
console.log(Object.keys(person))
console.log('-------------------------Object.keys----------------------------')
console.log(Object.getOwnPropertyNames(person))
console.log('-------------------------getOwnPropertyNames----------------------------')
console.log(Object.getOwnPropertySymbols(person))
console.log('-------------------------getOwnPropertySymbols----------------------------')
console.log(Reflect.ownKeys(person))
console.log('-------------------------Reflect.ownKeys----------------------------')
打印结果
name
type
-------------------------in关键字----------------------------
[ 'name' ]
-------------------------Object.keys----------------------------
[ 'name', 'sex' ]
-------------------------Object.getOwnPropertyNames----------------------------
[ Symbol(id) ]
-------------------------Object.getOwnPropertySymbols----------------------------
[ 'name', 'sex', Symbol(id) ]
-------------------------Reflect.ownKeys----------------------------
in 关键字
从上面的code可以看出
- in关键字循环对象时会把在原型链上的属性也遍历出来
- in关键字不会遍历Symbol属性,
- in关键字不会遍历访问属性enumerable为false的属性名
因为会把原型链的属性也遍历出来, 在用in关键字遍历对象时往往是搭配hasOwnProperty()来使用, 这样就可以只遍历自身的正常属性
for(let k in person) {
if (person.hasOwnProperty(k)) {
console.log(k)
}
}
Object.keys
解释: Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。
MDN解释
可以看出
- 不会得到Symbol属性
- 不会得到原型链的属性
- 不会得到 enumerable为false的属性
- 只会遍历正常的属性
Object.getPropertyNames
解释: Object.getOwnPropertyNames()方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
从上面的code可以看出
- 可以遍历enumerable:false的属性和正常属性
- 不可遍历原型链属性和Symbol属性
Object.getOwnPropertySymbols
解释: Object.getOwnPropertySymbols() 方法返回一个给定对象自身的所有 Symbol 属性的数组
MDN解释
- 只可以遍历Symbol属性
- 并不会遍历原型链上的Symbol属性
Reflect.ownKeys
解释: 静态方法 Reflect.ownKeys() 返回一个由目标对象自身的属性键组成的数组。
有打印结果可以看出
- 打印所有的自身属性,相等于getOwnPropertySymbols 和 getOwnPropertyNames两个方法的并集
- 不会打印原型链属性
for…of和iterator
for…of 可以遍历是一个iterator对象,在遍历的时候回查找对象的Sym’bol.iterator属性,如果有就调用得到一个遍历器对象来使用
如果有特殊需求需要使用for…of来遍历对象可以如此操作
person[Symbol.iterator] = function* () {
const keys = Reflect.ownKeys(this)
for (let i = 0; i < keys.length; i++) {
if (keys[i] !== Symbol.iterator) {
yield keys[i]
}
}
}
for(let k of person) {
console.log(k)
}
打印结果
name
sex
Symbol(id)