for...in 和for...of的区别

本文详细介绍了JavaScript中的for...of和for...in循环的区别,强调for...of用于遍历数组和迭代器对象的值,而for...in遍历对象的键。for...in会包含自定义属性,而for...of则不会。同时,文章展示了for...of在字符串、Map和Set等数据结构中的应用,并提供了使用Object.keys()和Object.values()处理对象的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

① for of 可以遍历数组里的每一项(for of 遍历数组的值);一般不建议for in 遍历数组(for in 是遍历循环数组的索引(键值))

var arr = ['haha','heihei'];
for(var item of arr){
	console.log(item);
}
打印结果:'haha','heihei'
----------------------------------
var arr = ['haha','heihei'];
for(var item in arr){
	console.log(item);
}
打印结果:0,1
----------------------------------
var arr1 = [
	{name: 'one',age: 11},
	{name: 'two',age:22},
	{name: 'three',age: 33},
]
for(var item of arr1){
	console.log(item.name,item.age);
}
打印结果:
'one' 11
'two' 22
'three' 33

② for of 不适合遍历对象

var obj = {
	0: 'one',
	1: 'two'
}
for(var key in obj) {
	console.log(key,obj[key])
}
打印结果:
0 'one',
1 'two'
-------------------------------
for(var item of obj) {
	console.log(item)
}
打印结果:报错

如果想让对象可以使用for of循环,那就先使用Object.keys()获取对象的key值集合后,再使用for of

let obj = {a: '1', b: '2', c: '3', d: '4'}
for (let o of Object.keys(obj)) {
    console.log(o) // a,b,c,d
}

或者使用内置的Object.values()方法获取对象的value值再使用for of

let obj = {a: '1', b: '2', c: '3', d: '4'}
for (let o of Object.values(obj)) {
    console.log(o) // 1,2,3,4
}

③ for in 会遍历自定义属性,for of不会;给数组添加一个自定义属性,然后赋值给数组,遍历,for in 会把自定义属性输出,for of 不会。

var arr = ['one', 'two', 'three'];
arr.name = 'andy';
for(var key in arr) {
	console.log(key+':'+arr[key]);
}
打印结果:
0:'one'
1:'two'
2:'three'
name:'andy'
--------------------------------
for(var item in arr) {
	console.log(item);
}
打印结果:
'one'
'two'
'three'

拓展:
for of 还可以循环一个字符串:

let str = 'love';
for(let o of str){
	console.log(o);
}
打印结果:
l,o,v,e

循环一个Map:

let iterable = new Map([['a',1],['b',2],['c',3]]);
for(let [key, value] of iterable){
	console.log(value)
}
打印结果:
1
2
3
---------------------------
for(let entity of iterable){
	console.log(entity)
}
打印结果:
[a,1]
[b,2]
[c,3]

循环一个set:

let iterable = new Set([1,1,2,2,3,3]);
for(let value of iterable){
	console.log(value)
}
打印结果:
1
2
3
<think>我们正在讨论JavaScript中的循环:for...infor...of。根据引用[1]中提到的“5.2Loops5.2.1For-In”,我们可以知道for...in循环是JavaScript中的一种循环结构。但是引用中并没有详细说明for...of,因此我们需要结合其他知识。另外,引用[5]提到了回调函数的使用,但与我们当前的问题无关。引用[2]提到了一些高级特性,如生成器符号,但也没有直接涉及循环。引用[3]是关于数据获取的副作用处理,引用[4]是JavaScript的总体介绍。因此,我们主要依靠自己的知识来回答,但注意引用[1]中提到了for-in循环,所以我们可以从那里开始。目标:解释for...infor...of循环的区别,并给出使用场景示例。步骤:1.定义for...in循环:用于遍历对象的可枚举属性(包括继承的属性)。2.定义for...of循环:用于遍历可迭代对象(如数组、字符串、Map、Set等)的元素。3.比较两者:主要区别在于它们遍历的内容不同(属性vs元素)。4.使用场景:for...in适合遍历对象属性,for...of适合遍历数组等可迭代对象。5.注意事项:for...in会遍历原型链上的可枚举属性,通常我们使用hasOwnProperty来过滤;for...of是ES6引入的,不能直接用于普通对象(除非对象实现了可迭代协议)。6.示例:分别给出两个循环的代码示例。根据引用[1]中提到的“For-In”,我们可以引用该部分作为for...in的参考。回答结构:-首先介绍两种循环。-分别详细说明。-比较差异。-示例代码。-使用场景。最后生成相关问题。注意:在回答中,如果引用了给定的引用,需要在引用的段落末尾添加引用标识。我们只引用了[1]中关于for-in循环的部分,所以可以在提到for-in循环时添加引用标识。由于用户要求使用中文,所以整个回答用中文。</think>### JavaScript 中 `for...in` 与 `for...of` 循环的区别及使用场景 #### 1. **核心区别** | **特性** | `for...in` 循环 | `for...of` 循环 | |----------------|----------------------------------|----------------------------------| | **遍历对象** | 对象的 **可枚举属性**(包括继承属性) | 可迭代对象的 **元素值**(如数组、Map) | | **返回值** | 属性名(键名) | 元素值(键值) | | **适用对象** | 普通对象、数组(不推荐) | 数组、字符串、Map、Set 等可迭代对象 | | **原型链属性** | 默认遍历(需用 `hasOwnProperty` 过滤) | 不遍历原型链属性 | | **引入版本** | ECMAScript 1 | ECMAScript 6 (ES6) | #### 2. **使用场景与示例** **场景 1:遍历对象属性(`for...in`)** 适用于获取对象的键名(如配置项、键值对数据): ```javascript const user = { name: "Alice", age: 30, role: "Admin" }; for (const key in user) { if (user.hasOwnProperty(key)) { // 过滤继承属性 console.log(`属性名: ${key}, 值: ${user[key]}`); } } // 输出: // 属性名: name, 值: Alice // 属性名: age, 值: 30 // 属性名: role, 值: Admin ``` **场景 2:遍历数组元素(`for...of`)** 适用于直接获取数组、字符串等可迭代对象的值: ```javascript const colors = ["red", "green", "blue"]; // 直接获取元素值 for (const color of colors) { console.log(color); } // 输出:red, green, blue // 字符串遍历 for (const char of "Hello") { console.log(char); } // 输出:H, e, l, l, o ``` **场景 3:遍历 Map/Set(`for...of`)** 适用于 ES6 新增数据结构: ```javascript const map = new Map([["a", 1], ["b", 2]]); for (const [key, value] of map) { console.log(`${key} => ${value}`); } // 输出:a => 1, b => 2 const set = new Set([10, 20, 30]); for (const num of set) { console.log(num); } // 输出:10, 20, 30 ``` #### 3. **常见误区** - **数组遍历避免用 `for...in`**: 会遍历数组的**非数字属性**(如添加的自定义属性)**原型链方法**: ```javascript Array.prototype.customMethod = () => {}; const arr = [1, 2, 3]; arr.foo = "bar"; for (const key in arr) { console.log(key); // 输出:0, 1, 2, foo, customMethod(意外结果!) } ``` - **普通对象不能用 `for...of`**: 除非对象实现迭代器协议(如添加 `[Symbol.iterator]` 方法)。 #### 4. **性能与兼容性** - **性能**:`for...of` 通常比 `for...in` 更快(因无需检查原型链)。 - **兼容性**:`for...in` 支持所有浏览器;`for...of` 需 ES6+ 环境(IE 不支持)。 --- ### 相关问题 1. 如何用 `for...in` 安全遍历对象属性而不包含继承属性? 2. 普通对象如何实现迭代器协议以支持 `for...of` 循环? 3. 在遍历数组时,`for...of` 与传统的 `for` 循环有何性能差异? 4. `for...of` 循环能否遍历类数组对象(如 `arguments` 或 DOM 集合)? 5. 如何用 `for...of` 同时获取数组的索引值? [^1] [^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值