对象属性遍历方法与差异
有很长一段时间,我都没有意识到遍历也是有区别的,都是统一使用for…in。实际上在根据属性名是否可枚举,是否继承,是否为symbol类型用不同的遍历方法得到的结果也不不同,所以在这里总结一下我知道的对象的各种遍历方法及其区别,如有遗漏,欢迎补充。
1、准备遍历的对象
prototypeObj 为obj的原型对象,以prototypeObj为构造函数创建了obj对象后,用各种方式遍历obj。并且其中有一个属性名是属于symbol类型,还有一个不可枚举属性sex
function prototypeObj () {
this.remark = 'obj对象的原型对象';
}
prototypeObj.prototype.name = '继承属性';
let symbolName = Symbol('d');
let obj = new prototypeObj();
obj.a = '111';
obj.b = '222';
obj.c = '333';
obj[symbolName] = '444';
// 设置不可枚举属性sex
Object.defineProperty(obj, "sex",{
value:"female",
enumerable:false
});
2、遍历
2.1、 for…in 循环
for…in 循环遍历对象自身的和继承的可枚举属性(不含Symbol属性)。
输出结果不包括symbolName以及sex。
for(let key in obj) {
console.log(key ,":", obj[key ]);
}
2.2、Object.keys方法遍历
Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
console.log(key ,":", obj[key ]);
2.3、Object.getOwnPropertyNames遍历
Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含Symbol属性,但是包括不可枚举属性)
console.log("Object.getOwnPropertyNames: " + Object.getOwnPropertyNames(obj));
2.4、Object.getOwnPropertySymbols
Object.getOwnPropertySymbols()可以返回对象自有的Symbol属性,原型链上的属性不会被获取。
可以看到只返回了Symbol类型的属性名。顺便提一下,symbol类型的值不能与其他类型的值进行运算,否则会报错,所以下面的打印方法拆开了。
console.log("Object.getOwnPropertySymbols: ");
console.log(Object.getOwnPropertySymbols(obj));
2.5、Reflect.ownKeys
Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管是属性名是Symbol或字符串,也不管是否可枚举。
console.log("Object.getOwnPropertySymbols: ");
console.log(Object.getOwnPropertySymbols(obj));