You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中Map与Object键值互换:为何Map会无限循环?

Map与Object互换键值时循环行为差异的原因

核心差异:迭代器的工作逻辑不同

1. Object的for...in循环:基于固定列表遍历

for...in在启动遍历前,会先收集对象当前所有可枚举属性的键,形成一个固定列表。后续对对象的修改(新增、删除属性)不会影响这个已经确定的遍历列表。

看你的代码执行流程:

const obj = { 1: "one", 2: "two" };
for (const key in obj) {  
 const value = obj[key];
 obj[value] = key
 delete obj[key];
}
console.log(obj); // { one: '1', two: '2' }

遍历开始时,for...in已经收集到['1', '2']两个键,哪怕循环中删除了原键、新增了新属性,遍历只会按这个固定列表执行两次,所以是有限循环。

2. Map的for...of循环:基于实时集合遍历

Map的迭代器是动态的,它会直接读取Map当前时刻的键值对集合,而不是先缓存固定列表。

你的Map循环执行流程:

const map = new Map([[1, "one"], [2, "two"]]);
for (const [key, value] of map) {  
  map.set(value, key);
  map.delete(key);
}
  • 第一次迭代:取出[1, "one"],删除1并新增"one" => 1,此时Map内容为[[2, "two"], ["one", 1]]
  • 第二次迭代:取出[2, "two"],删除2并新增"two" => 2,此时Map内容为[["one", 1], ["two", 2]]
  • 第三次迭代:取出["one", 1],删除"one"并新增1 => "one",Map回到[["two", 2], [1, "one"]]
  • 第四次迭代:取出["two", 2],删除"two"并新增2 => "two",Map又回到类似初始的状态
  • 以此往复,迭代器永远能读到新的键值对,陷入无限循环

让Map实现有限循环的解决办法

如果要安全地给Map互换键值,需要先把原有的键值对拷贝成固定数组,再遍历这个数组操作Map:

const map = new Map([[1, "one"], [2, "two"]]);
// 将Map转成数组,脱离原Map的动态集合
for (const [key, value] of Array.from(map)) {  
  map.set(value, key);
  map.delete(key);
}
console.log(map); // Map(2) { 'one' => 1, 'two' => 2 }

这样遍历的是初始的固定数组,不受后续Map修改的影响,自然会在两次迭代后结束。

内容的提问来源于stack exchange,提问作者hardy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:07:26