JavaScript中的for...of和for...in有什么区别?

来源:站长源码作者:深圳程序员头衔:程序员
导读:本期聚焦于小伙伴创作的《JavaScript中的for...of和for...in有什么区别?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JavaScript中的for...of和for...in有什么区别?》有用,将其分享出去将是对创作者最好的鼓励。

在JavaScript的循环语法中,for...of和for...in都是常用的遍历方式,但两者的设计逻辑和适用场景存在明显差异,很多开发者容易混淆两者的用法,导致遍历结果不符合预期。下面我们就来详细拆解两者的区别。

JavaScript中的for...of和for...in有什么区别?

核心设计目标不同

for...in是早期JavaScript就存在的循环语法,设计初衷是遍历对象的可枚举属性,包括对象自身的可枚举属性和从其原型链上继承的可枚举属性。而for...of是ES6新增的循环语法,设计目标是遍历可迭代对象(Iterable Object)的值,它依赖对象的迭代器实现,只能遍历符合可迭代协议的对象。

遍历数组时的表现差异

先来看遍历普通数组的情况,两者的输出结果完全不同:

const arr = [10, 20, 30];
// 给数组添加一个自定义属性
arr.customProp = 'test';

console.log('for...in遍历数组结果:');
for (const key in arr) {
  console.log(key); // 输出:0、1、2、customProp
}

console.log('for...of遍历数组结果:');
for (const value of arr) {
  console.log(value); // 输出:10、20、30
}

从结果可以看出,for...in遍历数组时拿到的是数组的索引(本质是字符串类型的属性名),还会遍历到数组自定义的属性;而for...of遍历数组时直接拿到数组的元素值,不会遍历自定义属性。

遍历普通对象时的差异

普通对象默认不是可迭代对象,因此for...of无法直接遍历普通对象,会直接抛出错误:

const obj = { name: '张三', age: 25, city: '北京' };

console.log('for...in遍历对象结果:');
for (const key in obj) {
  console.log(key, obj[key]); // 输出:name 张三、age 25、city 北京
}

console.log('for...of遍历对象结果:');
try {
  for (const value of obj) {
    console.log(value);
  }
} catch (e) {
  console.log(e.message); // 输出:obj is not iterable
}

如果要让for...of遍历普通对象,需要先获取对象的键、值或者键值对数组,再使用for...of遍历:

const obj = { name: '张三', age: 25, city: '北京' };

// 遍历对象的键
for (const key of Object.keys(obj)) {
  console.log(key); // 输出:name、age、city
}

// 遍历对象的值
for (const value of Object.values(obj)) {
  console.log(value); // 输出:张三、25、北京
}

// 遍历对象的键值对
for (const [key, value] of Object.entries(obj)) {
  console.log(key, value); // 输出:name 张三、age 25、city 北京
}

遍历其他数据类型的差异

除了数组和对象,两者在遍历字符串、Map、Set等类型时也有明显区别:

  • 遍历字符串:for...in会遍历字符串的索引,for...of会遍历字符串的每个字符
  • 遍历Map/Set:for...in无法遍历Map和Set的内容,for...of可以直接遍历Map的键值对或者Set的元素

看下面的示例:

const str = 'abc';
const set = new Set([1, 2, 3]);
const map = new Map([['a', 1], ['b', 2]]);

console.log('for...in遍历字符串:');
for (const key in str) {
  console.log(key); // 输出:0、1、2
}

console.log('for...of遍历字符串:');
for (const char of str) {
  console.log(char); // 输出:a、b、c
}

console.log('for...of遍历Set:');
for (const item of set) {
  console.log(item); // 输出:1、2、3
}

console.log('for...of遍历Map:');
for (const [key, value] of map) {
  console.log(key, value); // 输出:a 1、b 2
}

使用注意事项

  1. for...in遍历对象时,如果只需要遍历对象自身的可枚举属性,建议使用hasOwnProperty方法过滤原型链上的属性,避免拿到不需要的属性。
  2. 遍历数组时优先使用for...of,除非明确需要拿到数组的索引或者自定义属性,否则不要用for...in遍历数组,避免逻辑错误。
  3. for...of只能遍历可迭代对象,判断一个对象是否可迭代可以查看该对象是否有Symbol.iterator属性。
总结来说,for...in适合遍历对象的属性,for...of适合遍历可迭代对象的值,根据遍历的目标数据类型选择合适的循环方式,能减少很多不必要的bug。

for...offor...inJavaScript遍历迭代器修改时间:2026-06-05 02:12:33

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。