Map无法被JSON.stringify()直接序列化,需转为二维数组格式(如[[k1,v1],[k2,v2]])再序列化;反向用JSON.parse()解析后传入new Map()即可还原。

JavaScript中Map对象不能直接被JSON.stringify()序列化,JSON也不支持Map这种键值对结构(尤其当键不是字符串时),所以需要手动实现Map与JSON字符串的互相转换。核心思路是:**将Map转为可序列化的数组格式(如[[k1,v1],[k2,v2]]),再用JSON处理;反向则从JSON数组还原为Map实例。**
Map → JSON字符串:先转成二维数组,再序列化
因为Map的key可以是任意类型(函数、对象、Symbol等),而JSON只接受字符串作为键,所以通用做法是把Map转为键值对数组(Array of arrays),每个子数组长度为2,形如[[key, value], ...]。这个结构能保留原始key的类型信息(只要key本身可被JSON序列化)。
- 使用
Array.from(map)或[...map]快速获取键值对数组 - 调用
JSON.stringify()直接序列化该数组 - 若Map的key是函数、undefined、Symbol等不可序列化类型,需提前处理(如转为字符串描述、跳过或报错)
JSON字符串 → Map:解析后逐对构造Map
从JSON字符串还原Map时,先用JSON.parse()得到二维数组,再用该数组作为参数传入new Map()构造器即可。这是最简洁可靠的方式。
- 确保JSON字符串内容是合法的二维数组格式,例如
"[[\"name\",\"Tom\"],[\"age\",25]]" - 执行
new Map(JSON.parse(jsonStr)),Map构造器原生支持接收可迭代的键值对数组 - 如果原始Map的key是复杂类型(如Date、自定义对象),仅靠JSON无法还原——此时需额外约定序列化规则(如用
toJSON()方法或类型标记字段)
处理特殊key类型的补充策略
当Map的key包含Date、RegExp、自定义类实例等无法被JSON直接表示的值时,纯数组方案会丢失类型信息。可行的增强方式包括:
立即学习“Java免费学习笔记(深入)”;
- 序列化前将key标准化:例如
map.forEach((v, k) => arr.push([serializeKey(k), v])),其中serializeKey返回唯一字符串标识(如k instanceof Date ? `DATE:${k.toISOString()}` : String(k)) - 在JSON中增加元数据字段(如
{"type":"Map","data":[...]}),反序列化时根据type决定如何构造 - 避免在Map中使用不可序列化key——多数业务场景中,用字符串或数字作key已足够
封装成可复用的工具函数
把转换逻辑封装成两个函数,提升可读性和复用性:
-
mapToJson(map):内部调用JSON.stringify(Array.from(map)) -
jsonToMap(jsonStr):内部调用new Map(JSON.parse(jsonStr)) - 添加基础校验,比如判断输入是否为Map、JSON字符串是否合法,避免运行时报错
不复杂但容易忽略的是key的类型限制——只要Map的key能被JSON安全表达(通常是字符串、数字、布尔、null,或可被toString()明确区分的对象),二维数组方案就足够健壮。实际项目中,优先约束Map的key类型,比强行支持所有类型更可持续。


















