在 JavaScript 中,我们经常需要遍历数组、对象、字符串等结构。虽然可以使用 for
循环、forEach
、map
等方法,但 for...in
和 for...of
是两种专门为不同类型结构设计的循环语法。
本文将深入讲解 for...in
与 for...of
的本质区别、使用场景、优缺点,并通过具体示例帮助你更清晰地理解它们的用法。
一、for...in
是什么?
for...in
用于遍历对象的可枚举属性名(也就是键名),包括对象自身的属性和原型链上继承的属性。
✅ 语法:
js
for (const key in object) {
// key 是属性名(字符串)
}
✅ 示例:
js
const person = { name: 'Alice', age: 25 };
for (const key in person) {
console.log(key); // name, age
console.log(person[key]); // Alice, 25
}
⚠️ 注意事项:
- 遍历的是 key(键名) ,不是值;
- 包括原型链上的属性 ,所以通常需要使用
hasOwnProperty()
排除继承属性; - 不推荐用于数组,因为可能会遍历出非索引属性,顺序也不可靠。
二、for...of
是什么?
for...of
用于遍历可迭代对象的元素值,包括数组、字符串、Set、Map、arguments、DOM NodeList 等。
✅ 语法:
js
for (const value of iterable) {
// value 是每一项的值
}
✅ 示例(数组):
js
const numbers = [10, 20, 30];
for (const num of numbers) {
console.log(num); // 10, 20, 30
}
✅ 示例(字符串):
js
for (const char of 'hello') {
console.log(char); // h, e, l, l, o
}
✅ 示例(Set):
js
const set = new Set([1, 2, 3]);
for (const val of set) {
console.log(val); // 1, 2, 3
}
三、使用数组时的区别
js
const arr = ['a', 'b', 'c'];
arr.custom = 'hello';
🔹 for...in
遍历索引和自定义属性:
js
for (const index in arr) {
console.log(index); // 0, 1, 2, custom
}
🔹 for...of
只遍历值:
js
for (const value of arr) {
console.log(value); // a, b, c
}
四、区别总结对比表
对比项 | for...in |
for...of |
---|---|---|
遍历内容 | 属性名(key) | 元素值(value) |
可遍历对象 | 对象、数组(不推荐) | 可迭代对象(数组、字符串、Set、Map 等) |
包含原型链属性 | ✅ 是 | ❌ 否 |
可用于对象 | ✅ 是 | ❌ 否(除非实现了 Symbol.iterator) |
可用于数组 | ✅ 是(不推荐) | ✅ 是(推荐) |
遍历顺序可靠性 | ❌ 否 | ✅ 是 |
五、推荐使用方式
场景 | 推荐方式 |
---|---|
遍历数组/字符串/Set/Map | ✅ 使用 for...of |
遍历对象的键名 | ✅ 使用 for...in + hasOwnProperty() |
遍历对象的键值对 | ✅ 使用 Object.entries() + for...of |
六、实用技巧拓展
🚀 遍历对象的键值对推荐写法:
js
const obj = { a: 1, b: 2 };
for (const [key, value] of Object.entries(obj)) {
console.log(key, value); // a 1, b 2
}
七、结语
虽然 for...in
和 for...of
看起来语法类似,但它们的应用场景完全不同。了解它们各自的工作机制和最佳使用方式,能让你的代码更加清晰、安全且高效。
小结口诀:
- 遍历对象用
in
,记得排除继承属性;- 遍历数组用
of
,不带索引更稳妥。