structuredClone 可直接深拷贝含 Map 的复杂对象,支持 Map、Set、Date 等类型,但键不能为函数、undefined、Symbol 或循环引用;旧环境可用 postMessage 降级或 lodash.cloneDeep。

structuredClone 可以直接复制包含 Map(以及 Set、Date、RegExp、嵌套对象/数组等)的复杂结构,前提是目标环境支持该 API(Chrome 98+、Firefox 94+、Safari 15.4+,Node.js 17.0+ 默认启用,16.14+ 需加 --harmony-structured-cloning 标志)。
确认环境支持并使用基本语法
无需额外处理 Map,它属于 structuredClone 原生支持的可克隆类型:
- 直接传入含
Map的对象或数组,返回深拷贝结果 - 原
Map中的键值对(包括对象键、函数除外)会被完整复制 - 注意:
Map的键若为函数、undefined、Symbol(非全局注册)、或循环引用,会抛出DataCloneError
示例:
const original = {
name: "Alice",
scores: new Map([["math", 95], ["english", 88]]),
meta: { tags: ["student"] }
};
const cloned = structuredClone(original);
cloned.scores.set("science", 92); // 不影响 original.scores
console.log(original.scores.has("science")); // false
处理不支持环境的降级方案
如果运行在旧版浏览器或 Node.js 中,structuredClone 不可用,可:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用
JSON.stringify + JSON.parse—— 但Map会被丢弃(转为空对象),不可用 - 手动递归遍历 + 判断类型:遇到
Map实例时,新建Map并递归克隆其键值 - 使用成熟库如
lodash.cloneDeep(自动处理Map/Set,兼容性好)
注意 Map 键的限制
structuredClone 要求 Map 的键必须是可克隆类型:
- ✅ 支持:字符串、数字、布尔值、
null、普通对象、数组、其他Map/Set、Date、RegExp、ArrayBuffer等 - ❌ 不支持:
function、undefined、Symbol(即使全局 Symbol 也不行)、Promise、WeakMap、WeakSet、Error对象
例如以下会报错:
const badMap = new Map([[function() {}, "oops"]]);
structuredClone({ map: badMap }); // 抛出 DataCloneError
替代:用 postMessage 实现兼容性克隆(仅限浏览器)
在不支持 structuredClone 但需要克隆 Map 的老浏览器中,可利用 postMessage 的结构化克隆机制(与 structuredClone 同一底层):
function fallbackClone(obj) {
return new Promise(resolve => {
const channel = new MessageChannel();
channel.port1.onmessage = e => resolve(e.data);
channel.port2.postMessage(obj);
});
}
// 使用(需 await)
// const cloned = await fallbackClone(original);
⚠️ 注意:此方式异步,且不能传递函数、DOM 节点等;适合一次性数据迁移场景。

















