JavaScript遍历应按数据结构选择:对象用Object.keys()/values()/entries()避免原型污染,数组优先for...of;for...in仅适用于对象且需hasOwnProperty过滤,禁用于数组。

JavaScript 中遍历对象和数组的方法很多,但不是所有都适合你的场景——关键看你要不要处理原型链、是否需要兼容旧环境、是否要跳过不可枚举属性,或者是否在写函数式风格代码。
for...in 会遍历对象的可枚举属性(包括继承的)
它常被误用于数组,但实际是为对象设计的。问题在于:for...in 会遍历原型链上的可枚举属性,且不保证顺序(尤其在数字键混杂时)。
- 遍历对象时,用
Object.prototype.hasOwnProperty.call(obj, key)过滤掉继承属性 - 绝对不要用
for...in遍历数组——它会把数组方法(如push、map)也当作键遍历,如果原型被污染就更危险 - ES6 后更推荐用
Object.keys()+for...of或forEach
Object.keys() / Object.values() / Object.entries() 是安全遍历对象的起点
这三个方法只返回对象**自身**的可枚举属性,不触碰原型链,返回值都是数组,因此能直接使用数组方法。
-
Object.keys(obj)返回字符串键名数组,适合需要操作 key 的场景 -
Object.values(obj)返回值数组,注意:值的顺序与Object.keys()严格对应(ES2017+) -
Object.entries(obj)返回[key, value]二元数组,配合解构最简洁:for (const [k, v] of Object.entries(obj)) { ... } - 它们都不处理 symbol 键;要包含 symbol,得用
Reflect.ownKeys()
数组遍历优先选 for...of,而不是 for...in 或传统 for 循环
for...of 直接消费迭代器,语义清晰、无索引管理负担,且天然支持 break/continue,比 forEach 更灵活。
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
立即学习“Java免费学习笔记(深入)”;
-
for (const item of arr) { ... }—— 最简写法,适用于只需值的场景 -
for (const [i, item] of arr.entries()) { ... }—— 需要索引时的推荐写法,比手动维护i++安全 -
arr.forEach((item, i) => { ... })—— 不能用break,且无法用await(异步回调需改用for...of) - 传统
for (let i = 0; i 在性能敏感循环中仍有价值,但多数业务代码没必要
Map 和 Set 的遍历比普通对象更直观
如果你本就可以控制数据结构,优先用 Map 替代对象存键值对,用 Set 替代去重数组——它们的遍历接口统一、语义明确、不污染原型。
-
map.forEach((value, key) => { ... })和for (const [key, value] of map)效果一致 -
set.forEach(value => { ... })或for (const value of set),没有歧义 - 注意:
Map的键可以是任意类型(包括对象、函数),而对象只能用字符串或 symbol 作键 - 从对象转
Map:new Map(Object.entries(obj));反过来:Object.fromEntries(map)
最容易被忽略的是:遍历前先想清楚「这个数据结构是谁创建的?有没有可能被代理/扩展/污染?」——比如后端返回的对象若带 __proto__ 字段,在低版本浏览器里可能意外触发原型污染。这时候用 Object.entries() 比 for...in 多一层保障,而用 Map 则彻底绕开这个问题。









