深入解析JavaScript中的for…in和for…of循环
在JavaScript中,for...in
和for...of
是两种常用的循环结构,它们允许我们遍历对象的属性或数组、字符串、Map、Set等可迭代对象的元素。尽管它们的目标相似,但在使用和功能上却存在一些重要的区别。本文将详细探讨这两种循环的用法、区别以及最佳实践。
1. for…in循环
for...in
循环用于遍历对象的可枚举属性。在每次迭代中,变量会被赋予一个属性名,而不是属性值。请注意,for...in
不仅会枚举出对象自身的属性,还会枚举出其原型链上的属性(除非该对象使用Object.prototype
的hasOwnProperty
方法来过滤掉原型链上的属性)。
基本语法
for (variable in object) { // 执行的代码块 }
示例
let obj = {a: 1, b: 2, c: 3}; for (let prop in obj) { console.log(`属性名: ${prop}, 属性值: ${obj[prop]}`); }
这段代码会输出:
属性名: a, 属性值: 1 属性名: b, 属性值: 2 属性名: c, 属性值: 3
注意事项
for...in
循环遍历的是对象的属性名,而不是属性值。for...in
会枚举出对象自身以及原型链上的所有可枚举属性。如果只想遍历对象自身的属性,可以使用hasOwnProperty
方法进行过滤。
2. for…of循环
for...of
循环是ES6引入的一种新的遍历命令,用于遍历可迭代对象的元素。与for...in
不同,for...of
循环直接遍历的是值,而不是键。
基本语法
for (variable of iterable) { // 执行的代码块 }
示例
let arr = [1, 2, 3, 4, 5]; for (let value of arr) { console.log(value); }
这段代码会输出:
1 2 3 4 5
注意事项
for...of
循环遍历的是可迭代对象的元素值,而不是属性名。for...of
循环不会遍历对象的原型链。for...of
循环适用于数组、字符串、Map、Set等可迭代对象。
3. for…in和for…of的区别
for...in
遍历的是对象的属性名,而for...of
遍历的是可迭代对象的元素值。for...in
会遍历对象自身以及原型链上的属性,而for...of
只遍历对象自身的元素。
for...in
适用于普通对象,而for...of
适用于可迭代对象,如数组、字符串、Map、Set等。
4. 最佳实践
- 当需要遍历对象的属性名时,使用
for...in
循环,并考虑使用hasOwnProperty
方法过滤掉原型链上的属性。 - 当需要遍历可迭代对象的元素值时,使用
for...of
循环。 - 对于数组和字符串等可迭代对象,优先考虑使用
for...of
循环,因为它更直接、更高效。
- 在使用
for...in
和for...of
循环时,注意确保遍历的对象是可枚举的或可迭代的,否则可能会导致错误或不可预期的结果。
5. 总结
for...in
和for...of
是JavaScript中两种常用的循环结构,它们在遍历对象时有着不同的特点和用法。for...in
主要用于遍历对象的属性名,而for...of
则用于遍历可迭代对象的元素值。在实际开发中,我们需要根据具体的需求和场景选择合适的循环结构,以确保代码的正确性和高效性。同时,我们还需要注意一些常见的陷阱和错误用法,以避免在遍历对象时出现问题。通过深入理解和掌握这两种循环的用法和区别,我们可以更加灵活和高效地使用JavaScript进行开发。
1、for of 默认情况下是调用对象的iterator,一般用于 Array, String ,Map, Set, arguments, DOM data。
let a = [{ name: "wre", age: 123 }, { name: "whhjkre", age: 123 }, { name: "wrhje", age: 123 }, { name: "wjhjre", age: 123 }] let obj = { name: "sfsd", age: 44, //加迭代器的方式 [Symbol.iterator]: () => { const keys = Object.keys(this); let index = 0; return { next: () => { return { value: [keys[index], this[keys[index++]]], // 每次迭代的结果 done: index > keys.length // 迭代结束标识 false停止迭代,true继续迭代 }; } } } } for (const key of obj) { //用来遍历对象会报错,因为没有iterator,给对象自定义一个iterator也可以用这个方法 console.log(key) //TypeError:obj is not iterable } for (const key of a) { // 遍历数组 console.log(key) //{ name: 'wre', age: 123 } //{ name: 'whhjkre', age: 123 } //{ name: 'wrhje', age: 123 } //{ name: 'wjhjre', age: 123 } }
2、for in 主要用于遍历Object对象的key
for (const key in a) { //遍历数组,输出数组下标就是一个指针 console.log(key) //0 //1 //2 //3 } for (const key in obj) { console.log(key); //name //age }
3、for of 遍历数组经常配合entries一起用,entries() 方法返回一个数组的迭代对象,该对象包含数组的键值对 (key/value)。
迭代对象中数组的索引值作为 key, 数组元素作为 value。
for (const [index, item] of a.entries()) { console.log(index, item) //0 { name: 'wre', age: 123 } //1 { name: 'whhjkre', age: 123 } //2 { name: 'wrhje', age: 123 } //3 { name: 'wjhjre', age: 123 } }