JavaScript中遍历对象的6种方式总结

 更新时间:2025年11月03日 10:39:10   作者:D_FW  
在日常的前端开发中,我们经常需要处理和操作 JavaScript 对象,本文将系统梳理 JavaScript 中遍历对象的 6 种方法,并结合实际场景告诉你:什么时候该用哪种方式?它们的区别是什么?如何避免常见坑,需要的朋友可以参考下

在日常的前端开发中,我们经常需要处理和操作 JavaScript 对象。无论是从接口获取的数据解析,还是状态管理中的数据重组,遍历对象都是一个高频且基础的操作。

然而,很多人只知道 for...in,却忽略了其他更现代、更高效的遍历方式。本文将系统梳理 JavaScript 中遍历对象的 6 种方法,并结合实际场景告诉你:什么时候该用哪种方式?它们的区别是什么?如何避免常见坑?

一、为什么遍历对象这么重要?

对象是 JavaScript 的核心数据类型之一。在 Vue、React、Redux、Axios 等框架和库中,对象无处不在:

  • 接口返回的 JSON 数据
  • 表单字段映射
  • 配置项动态处理
  • 国际化语言包
  • 缓存键值存储

掌握正确的遍历方式,不仅能提升代码可读性,还能避免性能问题和逻辑错误。

二、6 种遍历对象的方法详解

1. for...in 循环 —— 最基础但需谨慎使用

const user = { name: 'Alice', age: 25, city: 'Beijing' };
 
for (let key in user) {
  console.log(key, user[key]);
}

优点

  • 兼容性好,支持老浏览器
  • 可以遍历原型链上的可枚举属性(有时是优势)

缺点与风险

  • 会遍历到继承的可枚举属性,可能导致意外输出
  • 如果不加 hasOwnProperty 判断,容易出 bug

安全写法

for (let key in user) {
  if (user.hasOwnProperty(key)) {
    console.log(key, user[key]);
  }
}

适用场景:需要检查原型链属性的特殊情况(极少),否则不推荐作为首选。

2. Object.keys() —— 获取所有自身可枚举键

Object.keys(user).forEach(key => {
  console.log(key, user[key]);
});

优点

  • 只返回对象自身的可枚举属性
  • 返回数组,可链式调用 .map().filter() 等
  • 是现代开发中最常用的遍历方式之一

适用场景:你想“像数组一样”操作对象的键,比如筛选、转换等。

3. Object.values() —— 只关心值的时候用它

console.log(Object.values(user));
// ['Alice', 25, 'Beijing']
 
Object.values(user).forEach(value => {
  console.log(value);
});

优点:直接获取所有值,无需再通过 obj[key] 提取
适用场景:统计数值总和、批量处理值、导出为数组等。

4. Object.entries() 强烈推荐:获取键值对

这是 ES2017 引入的强大方法,返回 [key, value] 数组。

Object.entries(user).forEach(([key, value]) => {
  console.log(`${key}: ${value}`);
});

高级用法 1:转为 Map

const map = new Map(Object.entries(user));
console.log(map.get('name')); // 'Alice'

高级用法 2:过滤并重建对象

const filtered = Object.fromEntries(
  Object.entries(user).filter(([key, value]) => typeof value === 'string')
);
// { name: 'Alice', city: 'Beijing' }

适用场景:需要同时处理键和值、对象转换、动态重构等。这是现代 JS 开发的首选方式!

5. Object.getOwnPropertyNames() —— 包含不可枚举属性

有些属性是“隐藏”的,比如通过 Object.defineProperty 定义的不可枚举属性。

const obj = { a: 1 };
Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});
 
console.log(Object.keys(obj));           // ['a']
console.log(Object.getOwnPropertyNames(obj)); // ['a', 'b']

适用场景:深拷贝、元编程、属性复制等需要完整元信息的场景。

6. Reflect.ownKeys() —— 最全的遍历方式

它能拿到:

  • 所有字符串键
  • 所有 Symbol 键
  • 可枚举和不可枚举属性
const sym = Symbol('id');
const obj = { name: 'Bob' };
obj[sym] = 100;
 
console.log(Reflect.ownKeys(obj)); // ['name', Symbol(id)]

适用场景:编写库、框架、深拷贝工具时,确保不遗漏任何属性。

三、对比总结:该怎么选?

方法是否包含继承是否包含不可枚举是否包含 Symbol返回类型推荐指数
for...in✅ 是❌ 否❌ 否-⭐⭐☆
Object.keys()❌ 否❌ 否❌ 否字符串数组⭐⭐⭐⭐
Object.values()❌ 否❌ 否❌ 否值数组⭐⭐⭐⭐
Object.entries()❌ 否❌ 否❌ 否[k,v] 数组⭐⭐⭐⭐⭐
getOwnPropertyNames❌ 否✅ 是❌ 否字符串数组⭐⭐⭐☆
Reflect.ownKeys()❌ 否✅ 是✅ 是所有键数组⭐⭐⭐⭐

结论:90% 的场景推荐使用 Object.entries(),语义清晰、功能强大、兼容现代开发需求。

四、实战技巧 & 常见误区

误区 1:直接 JSON.stringify(Map) 或 JSON.stringify(Symbol)

const obj = { [Symbol('x')]: 1 };
console.log(JSON.stringify(obj)); // {} —— Symbol 被忽略!

解决方案:使用 Reflect.ownKeys() 处理 Symbol。

误区 2:认为 for...in 和 Object.keys() 一样

function Person() {}
Person.prototype.say = function() {};
 
const p = new Person();
p.name = 'Tom';
 
console.log(Object.keys(p)); // ['name']
for (let k in p) console.log(k); // name, say(包括原型方法!)

建议:除非特殊需求,优先使用 Object.keys() 或 entries()

技巧:快速转换对象结构

// 将 { id1: '张三', id2: '李四' } 转为数组
const users = Object.entries(obj).map(([id, name]) => ({ id, name }));

五、结语

遍历对象看似简单,实则暗藏玄机。选择合适的遍历方式,不仅能让你的代码更健壮,还能提升开发效率和可维护性。

记住一句话:“能用 Object.entries() 的地方,就不要用 for...in。”

随着 ES6+ 的普及,Object.keys/values/entries 已成为现代 JavaScript 的标准实践。掌握它们,是你迈向高级前端开发者的重要一步。

以上就是JavaScript中遍历对象的6种方式总结的详细内容,更多关于JavaScript遍历对象的资料请关注脚本之家其它相关文章!

相关文章

  • 基于JS实现移动端访问PC端页面时跳转到对应的移动端网页

    基于JS实现移动端访问PC端页面时跳转到对应的移动端网页

    不想通过CSS自适应在PC端和移动端分别显示不同的样式,那么只能通过在移动端访问PC端网页时跳转到对应的移动端网页了,那么怎么跳转呢,网上也有很多文章说明,以下实现思路经过小编测试过,需要的朋友可以参考下
    2016-04-04
  • JavaScript中Form表单技术汇总(推荐)

    JavaScript中Form表单技术汇总(推荐)

    这篇文章主要介绍了JavaScript中Form表单技术的相关资料,包括简单的表单验证和正则表达式验证,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • JavaScript设计模式之职责链模式应用示例

    JavaScript设计模式之职责链模式应用示例

    这篇文章主要介绍了JavaScript设计模式之职责链模式,结合实例形式分析了javascript责任链模式的概念、原理、使用方法及相关操作注意事项,需要的朋友可以参考下
    2018-08-08
  • CocosCreator入门教程之网络通信

    CocosCreator入门教程之网络通信

    这篇文章主要介绍了CocosCreator的网络通信,内容不多,涉及到的细节,读者可以根据实际情况,自己去延申
    2021-04-04
  • 如何实现iframe父子传参通信

    如何实现iframe父子传参通信

    这篇文章主要介绍了如何实现iframe父子传参通信,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • JS创建自定义表格具体实现

    JS创建自定义表格具体实现

    创建自定义表格的方法有很多,本文为大家介绍下使用js是如何创建的,感兴趣的朋友可以参考下
    2014-02-02
  • JS实现html页面点击下载文件的两种方式

    JS实现html页面点击下载文件的两种方式

    这篇文章主要介绍了JS实现html页面点击下载文件的两种方式,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Jil,高效的json序列化和反序列化库

    Jil,高效的json序列化和反序列化库

    下面小编就为大家带来一篇Jil,高效的json序列化和反序列化库。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • uniapp项目优化方式及建议

    uniapp项目优化方式及建议

    性能优化自古以来就是重中之重,本文关于uniapp项目优化方式最全整理,会根据开发情况进行补充,感兴趣的可以了解一下
    2021-08-08
  • 关于this和self的使用说明

    关于this和self的使用说明

    刚接触python的时候,最不习惯的事情,就是每个方法都要加一个self。无论Javascript还是C#,都直接一个this搞定,干嘛非要加一个变量self。
    2010-08-08

最新评论