for...of循环在遍历Set和Map时的注意事项有哪些?

简介: for...of循环在遍历Set和Map时的注意事项有哪些?

for...of 循环遍历 Set 和 Map 时的注意事项

一、遍历 Set 集合的注意事项

Set 是 JavaScript 中用于存储唯一值的有序集合,使用 for...of 遍历时需注意以下特性:

1. 遍历顺序与插入顺序一致

Set 集合遵循“插入顺序”,遍历时会按照元素添加的顺序依次输出。

const set = new Set([3, 1, 2]);
for (const item of set) {
   
  console.log(item); // 输出:3, 1, 2(与插入顺序一致)
}
2. 直接获取元素值,无需额外处理

Set 的每个元素本身就是值,for...of 可直接遍历元素,无需像数组一样通过索引获取。

const fruits = new Set(['apple', 'banana', 'orange']);
for (const fruit of fruits) {
   
  console.log(fruit); // 直接输出元素值
}
3. 无法通过索引操作元素

Set 没有索引概念,遍历时无法通过下标访问或修改元素(需通过 deleteclear 方法操作)。

const set = new Set([1, 2, 3]);
for (const item of set) {
   
  // 错误示例:无法通过索引修改
  // set[0] = 10; // 报错,Set 无索引属性
  if (item === 2) set.delete(item); // 正确方式:通过值删除
}
4. 与 forEach 的行为对比
  • for...of:可使用 break/continue 中断循环,支持 async/await
  • forEach:无法中断循环,需通过抛出异常终止。
    ```javascript
    const set = new Set([1, 2, 3, 4]);
    // for...of 可提前终止
    for (const item of set) {
    if (item === 3) break;
    console.log(item); // 输出:1, 2
    }

// forEach 无法直接终止,需抛出异常
set.forEach(item => {
if (item === 3) throw new Error('终止循环');
console.log(item);
});



##### 5. **遍历 Symbol 类型元素**
Set 支持存储 Symbol 类型,for...of 可正常遍历(需注意 Symbol 的唯一性)。
```javascript
const sym1 = Symbol('a');
const sym2 = Symbol('b');
const set = new Set([sym1, sym2]);
for (const sym of set) {
  console.log(sym); // 输出 Symbol(a), Symbol(b)
}

二、遍历 Map 集合的注意事项

Map 是键值对的有序集合,每个元素为 [key, value] 数组,for...of 遍历时需特殊处理键值对。

1. 直接获取键值对数组

for...of 遍历 Map 时,每个迭代项是包含 [key, value] 的数组,需解构赋值获取键值。

const map = new Map([
  ['name', 'John'],
  ['age', 30],
  ['city', 'New York']
]);

// 解构获取键值
for (const [key, value] of map) {
   
  console.log(`${
     key}: ${
     value}`); 
  // 输出:name: John, age: 30, city: New York
}
2. 遍历顺序与插入顺序一致

Map 同样遵循插入顺序,遍历时键值对的顺序与添加时一致。

const map = new Map();
map.set(2, 'two');
map.set(1, 'one');
map.set(3, 'three');

for (const [key, val] of map) {
   
  console.log(key); // 输出:2, 1, 3(插入顺序)
}
3. 结合 keys()/values()/entries() 方法

Map 提供三种遍历方法,需配合 for...of 使用:

  • map.keys():遍历所有键。
  • map.values():遍历所有值。
  • map.entries():遍历所有键值对(默认行为)。
    ```javascript
    // 遍历键
    for (const key of map.keys()) {
    console.log(key); // 2, 1, 3
    }

// 遍历值
for (const val of map.values()) {
console.log(val); // two, one, three
}

// 等价于直接遍历 map
for (const item of map.entries()) {
console.log(item); // [2, 'two'], [1, 'one'], [3, 'three']
}



##### 4. **键的类型支持**
Map 的键可以是任意类型(包括对象、函数、Symbol 等),for...of 遍历时需注意:
```javascript
const obj = { id: 1 };
const map = new Map();
map.set(obj, 'object-key');
map.set(Symbol('sym'), 'symbol-key');

for (const [key, val] of map) {
  console.log(`${typeof key}: ${val}`); 
  // 输出:object: object-key, symbol: symbol-key
}
5. 与 forEach 的区别
  • for...of:可通过解构获取键值,支持中断循环。
  • forEach:通过回调函数接收 (value, key, map) 三个参数,无法中断。
    map.forEach((value, key, map) => {
         
    console.log(`${
           key}: ${
           value}`);
    // 无法使用 break/continue,需通过逻辑控制是否继续
    });
    

三、通用注意事项(Set/Map 共通)

  1. 遍历期间修改集合的影响

    • 在 for...of 循环中添加或删除元素可能导致 不可预测的结果(不同浏览器实现可能不同),建议避免。
      const set = new Set([1, 2, 3]);
      for (const item of set) {
             
      if (item === 2) set.add(4); // 不建议在遍历中修改集合
      }
      
  2. 与迭代器的兼容性

    • Set 和 Map 都实现了 Iterator 接口,for...of 本质上是对迭代器的封装,可配合 next() 方法手动控制遍历。
      const set = new Set([1, 2, 3]);
      const iterator = set[Symbol.iterator]();
      console.log(iterator.next()); // { value: 1, done: false }
      
  3. 空集合的处理

    • 当 Set 或 Map 为空时,for...of 循环不会执行任何代码块,无需额外判断 size === 0

四、最佳实践建议

  1. Set 遍历场景

    • 当需要按插入顺序遍历唯一值时,直接使用 for...of。
    • 若需过滤元素,可结合 Array.from(set).filter() 转换为数组处理。
  2. Map 遍历场景

    • 使用解构赋值 [key, value] 同时获取键值对。
    • 若仅需键或值,优先使用 keys()values() 提升可读性。
  3. 避免遍历中修改集合

    • 如需修改,建议先将集合转换为数组(如 [...set]),再遍历处理。

通过理解 for...of 在 Set 和 Map 中的遍历特性,可更高效地处理集合数据,同时避免因特性不熟悉导致的逻辑错误。

相关文章
|
3月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
293 1
|
6月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
487 1
|
3月前
|
存储 算法 容器
set_map的实现+set/map加持秒杀高频算法题锻炼算法思维
`set`基于红黑树实现,支持有序存储、自动去重,增删查效率为O(logN)。通过仿函数可自定义排序规则,配合空间配置器灵活管理内存。不支持修改元素值,迭代器失效需注意。`multiset`允许重复元素。常用于去重、排序及查找场景。
|
3月前
|
存储 Java Go
【Golang】(3)条件判断与循环?切片和数组的关系?映射表与Map?三组关系傻傻分不清?本文带你了解基本的复杂类型与执行判断语句
在Go中,条件控制语句总共有三种if、switch、select。循环只有for,不过for可以充当while使用。如果想要了解这些知识点,初学者进入文章中来感受吧!
179 1
|
7月前
|
存储 安全 JavaScript
如何在不影响遍历的情况下从Set中删除元素?
如何在不影响遍历的情况下从Set中删除元素?
365 120
|
7月前
|
存储 安全
for...of循环在遍历Set时,如何正确添加元素?
for...of循环在遍历Set时,如何正确添加元素?
276 59
|
7月前
|
安全 Java 数据库连接
让我们讲解一下 Map 集合遍历的方式
我是小假 期待与你的下一次相遇 ~
289 43
|
7月前
|
存储 安全
for...of循环遍历Set时,如何删除元素?
for...of循环遍历Set时,如何删除元素?
329 57
|
10月前
使用 entrySet 遍历 Map 类集合 KV
使用 entrySet 遍历 Map 类集合 KV

热门文章

最新文章