JavaScript 遍历对象的五种核心方式详解

作者:青柠

时间:2026-10-24

浏览:161

本文详细解析JavaScript中遍历对象的五种主要方式,包括for...in、Object.keys、Object.getOwnPropertyNames、Object.getOwnPropertySymbols以及Reflect.ownKeys。通过对比它们对可枚举、不可枚举及Symbol类型属性的处理差异,帮助开发者根据实际需求选择最合适的遍历方法,并附带Object.values、Object.entries及hasOwnProperty等扩展用法的说明。

文章目录

准备

首先构建一个用于测试的对象实例obj。

代码清单1


var notEnum = Symbol("继承不可枚举symbol");
var proto = {
    [Symbol("继承可枚举symbol")]: "继承可枚举symbol",
    name: "继承可枚举属性"
};
// 不可枚举属性
Object.defineProperty(proto, "age", {
    value: "继承不可枚举属性"
});
// 不可枚举symbol属性
Object.defineProperty(proto, notEnum, {
    value: "继承不可枚举symbol"
});

var obj = {
    job1: "自有可枚举属性1",
    job2: "自有可枚举属性2",
    [Symbol("自有可枚举symbol")]: "自有可枚举symbol"
};
// 继承
Object.setPrototypeOf(obj, proto);
// 不可枚举属性
Object.defineProperty(obj, "address", {
    value: "自有不可枚举属性"
});
// 不可枚举symbol属性
var ownNotEnum = Symbol("自有不可枚举symbol");
Object.defineProperty(obj, ownNotEnum, {
    value: "自有不可枚举symbol"
});

五种武器

for…in

这是对象遍历领域中最经典的方法。通过该方式可以遍历对象自身以及其原型链上所有可枚举的属性,但不会包含Symbol类型的属性。

代码清单2


for(var attr in obj){
    console.log(attr,"==",obj[attr]);
}
/*
job1 == 自有可枚举属性1
job2 == 自有可枚举属性2
name == 继承可枚举属性
*/

Object.keys

该方法返回一个数组,包含对象自身所有可枚举属性的键名,同样不包含Symbol类型的属性。

代码清单3


Object.keys(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
job1 == 自有可枚举属性1
job2 == 自有可枚举属性2
*/

Object.getOwnPropertyNames

此方法返回一个数组,包含对象自身所有非Symbol类型的属性名称,无论这些属性是否可枚举。

代码清单4


Object.getOwnPropertyNames(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
job1 == 自有可枚举属性1
job2 == 自有可枚举属性2
address == 自有不可枚举属性
*/

Object.getOwnPropertySymbols

该方法返回一个数组,包含对象自身所有Symbol类型的属性名称,无论其是否可枚举。

代码清单5


Object.getOwnPropertySymbols(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
Symbol(自有可枚举symbol) == 自有可枚举symbol
Symbol(自有不可枚举symbol) == 自有不可枚举symbol
*/

Reflect.ownKeys

这是功能最全面的API,返回一个数组,包含对象自身所有的属性名称,既包括不可枚举的属性,也涵盖Symbol类型的属性。

代码清单6


Reflect.ownKeys(obj).map((attr)=>{
    console.log(attr,"==",obj[attr]);
});
/*
job1 == 自有可枚举属性1
job2 == 自有可枚举属性2
address == 自有不可枚举属性
Symbol(自有可枚举symbol) '==' '自有可枚举symbol'
Symbol(自有不可枚举symbol) '==' '自有不可枚举symbol'
*/

总结

如同武器库的使用手册,开发者应根据具体场景选择最合适的遍历工具。

api 操作 自身属性 不可枚举属性 继承属性 Symbol属性
for…in 遍历 yes no yes no
Object.keys 返回属性数组 yes no no no
Object.getOwnPropertyNames 返回非Symbol属性数组 yes yes no no
Object.getOwnPropertySymbols 返回Symbol属性数组 yes yes no yes
Reflect.ownKeys 返回属性数组 yes yes no yes

在五种方法中,Reflect.ownKeys最为强大,它能同时处理Symbol和不可枚举属性,效果相当于Object.getOwnPropertyNames与Object.getOwnPropertySymbols的结合体。

扩展

Object.values

该方法返回一个数组,包含对象自身所有可枚举属性的值,不包含Symbol类型的属性。

代码清单7


Object.values(obj).map((val)=>{
    console.log(val);
});
/*
自有可枚举属性1
自有可枚举属性2
*/

Object.entries

此方法返回一个二维数组,包含对象自身所有可枚举属性的键值对,同样不包含Symbol类型的属性。

代码清单7


Object.entries(obj).map((val)=>{
    console.log(val);
});
/*
[ 'job1', '自有可枚举属性1' ]
[ 'job2', '自有可枚举属性2' ]
*/

hasOwnProperty

用于检测对象自身是否包含指定的属性,返回布尔值。

注意:MDN指出JavaScript并未保护hasOwnProperty属性名,因此对象可能覆盖该属性。建议始终使用原型链上的Object.prototype.hasOwnProperty.call(obj, attr)来确保正确性。

代码清单8


for(var attr in obj){
    if(Object.prototype.hasOwnProperty.call(obj,attr)){
        console.log("自有属性::",attr);
    }else{
        console.log("继承属性::",attr);
    }
}
/*
自有属性:: job1
自有属性:: job2
继承属性:: name
*/

propertyIsEnumerable

用于检测指定属性在对象中是否可枚举,返回布尔值。

代码清单9


Reflect.ownKeys(obj).map((attr) => {
    if (Object.prototype.propertyIsEnumerable.call(obj, attr)) {
        console.log("可枚举属性::", attr);
    } else {
        console.log("不可枚举属性::", attr);
    }
});
/*
可枚举属性:: job1
可枚举属性:: job2
不可枚举属性:: address
可枚举属性:: Symbol(自有可枚举symbol)
不可枚举属性:: Symbol(自有不可枚举symbol)
*/

参考

MDN Object

总结

至此,关于JavaScript遍历对象的五种方式介绍完毕。如需了解更多相关内容,请查阅本站往期文章或继续浏览后续文章,感谢支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章