本人详细介绍了JS遍历对象N种方法,欢迎关注收藏。
遍历对象属性有五种方法,下图为一个场景对比图。
可以注意到两点:
- 只有for ... in 才可以遍历原型链属性,且只能遍历可枚举属性。
- Object.getOwnPropertyNames + Object.getOwnPropertySymbols = Reflect.ownKeys.
以上五种方法,用如下代码来做例子:
let obj = {enum_prop: "enum_val",[Symbol("symbol")]: "symbol"
};Object.defineProperty(obj,
"no_enum_prop",
{value: "no_enum_val", enumerable: false});Object.getPrototypeOf(obj).proto_enum_prop = "proto_enum_prop";
Object.keys
返回一个数组,包含对象自身所有enumerable属性(不含Symbol属性)的键名。
console.log(Object.keys(obj));
// 输出:["enum_prop"]
类似的其他两个函数为Object.values() 和Object.entries()。
console.log(Object.values(obj));
// 输出:["enum_val"]
console.log(Object.entries(obj));
// 输出:[[enum_prop: "enum_val"]]
for ... in
循环遍历对象自身和prototype的可枚举属性(不含Symbol属性)
for(let prop in obj){console.log(prop);
}
// 输出: enum_prop proto_enum_prop
Object.getOwnPropertyNames(obj)
返回一个数组,包含对象自身所有可枚举和不可枚举属性的(不含Symbol属性)的键名
console.log(Object.getOwnPropertyNames(obj));
// 输出:["enum_prop", "no_enum_prop"]
Object.getOwnPropertySymbols(obj)
返回一个数组,包含对象自身的所有Symbol属性的键名。
console.log(Object.getOwnPropertySymbols(obj));
// 输出:[Symbol(symbol)]
Reflect.ownKeys(obj)
返回数组,包含对象自身可枚举属性、不可枚举属性和Symbol属性。
console.log(Reflect.ownKeys(obj));
// 输出:["enum_prop", "no_enum_prop", Symbol(symbol)]
对象属性的顺序
对于对象属性的顺序,经常看到的说法是:ES5 没有制定,ES6按照如下方式:
- 值为整形的按照升序排序。
- 普通字符串的按照插入顺序。
- Symbol按照插入顺序。
但是,以下是我从MDN上找到:
for ... in: 返回的属性顺序是不确定的。以下来自MDN文档:
Object.keys(obj):返回顺序与for ... in 相同。以下来自MDN文档:
Object.getOwnPropertyNames(obj):返回顺序中可枚举属性和 for ...in相同,不可枚举属性的顺序没有定义,参见:
Object.getOwnPropertySymbols和Reflect.ownKeys,MDN文档没有说明顺序。
总结来说:避免依赖对象属性的顺序。