Map 支持解构赋值是因为其 prototype[Symbol.iterator] 已按规范定义为返回键值对数组的迭代器,满足 ES6 可迭代协议,从而天然支持 for...of 和结构化解构。
![如何利用 map.prototype[symbol.iterator] 实现对映射表的自定义解构赋值](https://img.php.cn/upload/article/001/242/473/177854479849360.png?x-oss-process=image/resize,p_40)
Map.prototype[Symbol.iterator] 是 Map 对象默认的迭代器方法,它返回一个遍历器对象,按插入顺序依次产出 [key, value] 数组。正因如此,Map 天然支持解构赋值和 for...of 遍历——你不需要额外实现,就能直接用结构化方式提取键值对。
为什么 Map 支持解构赋值?
因为 Map.prototype[Symbol.iterator] 已经被规范定义为返回一个迭代器,每次调用 .next() 都返回形如 { value: [key, value], done: false } 的对象。这恰好满足 ES6 解构赋值对可迭代对象(Iterable)的要求。
也就是说,只要一个对象的 [Symbol.iterator] 方法存在并符合迭代协议,它就能用于:
for (const [k, v] of map) { ... }-
const [[k1, v1], [k2, v2]] = map;(解构前两项) -
const [first, ...rest] = map;(配合扩展运算符)
基础解构:直接获取键值对数组
最常见用法是批量解构前 N 个条目:
示例:const m = new Map([['a', 1], ['b', 2], ['c', 3]]);<br> const [[x, y], [p, q]] = m;<br> console.log(x, y); // 'a', 1<br> console.log(p, q); // 'b', 2
这里没有手动调用 [Symbol.iterator],但引擎内部正是通过它获取迭代器,再逐次取值完成解构。
自定义“解构行为”:封装成函数或生成器
若想实现更灵活的解构逻辑(比如只取 value、跳过某些 key、或按条件过滤),可基于 map[Symbol.iterator]() 构建新迭代器:
- 用
map[Symbol.iterator]()获取原始迭代器 - 包装它的
next()方法,加入筛选/映射逻辑 - 返回一个新对象,带自己的
[Symbol.iterator]
function* valuesOnly(map) {<br>
for (const [, value] of map) yield value;<br>
}<br>
const m = new Map([['x', 10], ['y', 20]]);<br>
const [a, b] = valuesOnly(m); // a=10, b=20
注意边界情况
解构赋值依赖迭代器的返回顺序和数量,需留意:
- Map 迭代严格按插入顺序,不是键字典序
- 解构项数超过 Map 大小时,多余变量为
undefined(非报错) - 不能直接解构出「纯 key 数组」或「纯 value 数组」——必须显式遍历转换,例如:
const keys = [...m.keys()]; - 若重写了
map[Symbol.iterator],会覆盖默认行为(一般不建议)










