【js篇】for...in与 for...of 的区别:前端开发中的迭代器选择

在 JavaScript 中,for...infor...of 都是用于遍历数据结构的循环语句,但它们的应用场景和行为有显著差异。理解两者的区别对于编写高效、可维护的代码至关重要。


✅ 一句话总结

for...in 用于遍历对象的可枚举属性名(键) ,适合处理普通对象;而 for...of 用于遍历实现了 Symbol.iterator 接口的可迭代对象的值,适用于数组、字符串、Map、Set 等。


✅ 一、for...in 循环

🔹 语法

javascript 复制代码
for (variable in object) {
  // 执行语句
}

🔹 特点

  • 遍历对象的所有可枚举属性(包括原型链上的);
  • 返回的是属性名(字符串),不是值;
  • 主要用于普通对象(Plain Object) 的遍历;

🔹 示例

javascript 复制代码
const obj = { a: 1, b: 2, c: 3 };

for (let key in obj) {
  console.log(key);        // 输出: a, b, c
  console.log(obj[key]);   // 输出: 1, 2, 3
}

🔹 注意事项

  1. 会遍历原型链上的可枚举属性
javascript 复制代码
Object.prototype.extra = 'extra';

for (let key in obj) {
  console.log(key); // a, b, c, extra
}

✅ 建议使用 hasOwnProperty() 过滤:

javascript 复制代码
for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key, obj[key]);
  }
}
  1. 不推荐用于数组索引遍历
    • 虽然可以遍历数组,但顺序可能不稳定;
    • 可能会遍历到手动添加的非数字属性;
javascript 复制代码
const arr = [10, 20, 30];
arr.name = 'numbers';

for (let i in arr) {
  console.log(i); // 0, 1, 2, name(包括非索引属性)
}

✅ 二、for...of 循环

🔹 语法

javascript 复制代码
for (variable of iterable) {
  // 执行语句
}

🔹 特点

  • 遍历实现了 [Symbol.iterator]() 方法的可迭代对象
  • 返回的是元素的值,不是键;
  • 适用于:ArrayStringMapSetarguments、NodeList 等;

🔹 示例

javascript 复制代码
const arr = [10, 20, 30];

for (let value of arr) {
  console.log(value); // 输出: 10, 20, 30
}

const str = "hello";
for (let char of str) {
  console.log(char); // h, e, l, l, o
}

const map = new Map([['a', 1], ['b', 2]]);
for (let [key, value] of map) {
  console.log(key, value); // a 1, b 2
}

🔹 自定义对象也可使用 for...of

只要对象实现了 Symbol.iterator 接口:

javascript 复制代码
const myIterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
};

for (let value of myIterable) {
  console.log(value); // 1, 2, 3
}

✅ 三、核心区别对比表

特性 for...in for...of
遍历目标 对象的可枚举属性名(键) 可迭代对象的
适用类型 普通对象(Object) 数组、字符串、Map、Set、arguments、NodeList 等
是否遍历原型链
返回内容 属性名(字符串) 元素值
是否支持 break/continue
是否依赖 Symbol.iterator

✅ 四、常见误用与最佳实践

❌ 错误用法:用 for...in 遍历数组值

javascript 复制代码
// ❌ 不推荐
for (let i in arr) {
  console.log(arr[i]);
}

✅ 推荐使用:

javascript 复制代码
// ✅ 推荐
for (let value of arr) {
  console.log(value);
}

// 或使用数组方法
arr.forEach(value => console.log(value));

✅ 正确使用场景总结

数据类型 推荐循环方式
普通对象 {} for...in + hasOwnProperty
数组 [] for...offorEachmap
字符串 for...of
Map / Set for...of
arguments / NodeList for...of

✅ 五、一句话总结

for...in 遍历对象的 ,用 for...of 遍历可迭代对象的。选择正确的工具,让代码更清晰、更安全。


💡 拓展知识

🔹 如何判断一个对象是否可迭代?

javascript 复制代码
function isIterable(obj) {
  return obj != null && typeof obj[Symbol.iterator] === 'function';
}

isIterable([1, 2, 3]); // true
isIterable('hello');   // true
isIterable({});        // false

🔹 for...of 背后的机制

for...of 本质上是调用对象的 Symbol.iterator 方法,获取一个迭代器(Iterator),然后不断调用 .next() 方法直到 done: true

相关推荐
ViavaCos12 分钟前
pnpm v11 的安全策略,让我踩了个坑
前端
To_OC13 分钟前
从一段定时器代码,重新捋清 JS 同步、异步与 Promise
前端·javascript·代码规范
持敬chijing14 分钟前
Web渗透之前后端漏洞-XSS漏洞原理攻击防御全流程
前端·安全·web安全·网络安全·网络攻击模型·安全威胁分析·xss
程序员黑豆21 分钟前
AI全栈开发 - Java:注释
前端·后端·ai编程
痕忆丶30 分钟前
Typora 的替代marktext,marktext切换中文
前端
拙慕JULY35 分钟前
小程序返回 base64 文件报错
开发语言·javascript·小程序
数据知道37 分钟前
字体与排版防线:ClientRects 与系统字体枚举的底层拦截与伪造
javascript·数据采集·指纹浏览器·风控·浏览器指纹
羊羊小栈42 分钟前
Uplift营销供应链协同决策系统(基于Uplift因果推断与运筹优化算法)
前端·人工智能·算法·毕业设计·大作业
阿猫的故乡44 分钟前
Vue组合式函数(Composables)从入门到实战:鼠标跟踪、请求封装、本地存储……全案例拆解
前端·vue.js·计算机外设
Upsy-Daisy1 小时前
Hermes Agent 学习笔记 02:安装、配置与第一次运行
java·前端·数据库