structuredclone 是 html5 中用于安全深度复制 javascript 值的核心机制,支持保类型、保语义、无副作用的跨线程数据传递,兼容 date、map、blob 等 web api 类型,但不支持函数、error、dom 节点等。

StructuredClone 算法是 HTML5 中用于安全、深度复制 JavaScript 值的核心机制,它在 Worker、MessageChannel、postMessage() 等跨线程通信场景中自动启用,确保主线程与 Worker 线程之间传递的数据既完整又隔离。
为什么需要 StructuredClone 而不是浅拷贝或 JSON?
JavaScript 的原始赋值(=)是引用传递,直接共享内存地址,多线程下会引发竞态和数据污染;JSON.stringify/parse 虽能深拷贝,但只支持有限类型(丢弃函数、undefined、Date、RegExp、Map、Set、Blob、TypedArray 视图等),且无法处理循环引用。StructuredClone 则专门设计为支持 Web 平台常用结构化数据的**保类型、保语义、无副作用**复制。
StructuredClone 如何实现跨线程安全传递?
它不依赖共享内存,而是通过“序列化—传输—反序列化”三阶段完成:
-
序列化阶段:在发送方线程中,算法遍历对象图,识别可克隆类型(如 Array、Object、Date、RegExp、Map、Set、ArrayBuffer、TypedArray、Blob、File、ImageData 等),对每个值生成平台无关的内部表示;遇到不可克隆值(如函数、Error、DOM 节点、WeakMap)则抛出
DataCloneError。 - 传输阶段:序列化后的二进制数据通过内核级消息通道(如 Chromium 的 Mojo 或 Firefox 的 IPC)零拷贝或高效拷贝传递,不经过 JS 引擎,避免主线程阻塞。
- 反序列化阶段:接收方线程用相同算法重建新对象,所有引用关系被还原,但与原对象完全独立——例如两个 ArrayBuffer 克隆后指向不同内存块,修改一方不会影响另一方。
哪些数据能被 StructuredClone 正确处理?
以下类型在现代浏览器(Chrome 98+、Firefox 94+、Safari 15.4+)中默认支持:
- 基本类型:
null、undefined、boolean、number、string、bigint、symbol(仅限显式传入,但Symbol键在对象中会被忽略) - 对象结构:
Object、Array、Date、RegExp、Map、Set、ArrayBuffer、SharedArrayBuffer(注意:SharedArrayBuffer 不克隆,而是传递引用,需手动处理同步) - Web API 类型:
Blob、File、ImageData、ImageBitmap、DOMException(部分)、RTCDataChannel(有限支持)
不支持的典型例子:function、Error、Promise、Proxy、Generator、document 节点、window、console、undefined 作为对象属性值(某些旧版行为不一致)。
开发者需要注意的关键细节
尽管 StructuredClone 是自动启用的,但实际使用中仍需关注:
-
性能开销:深度嵌套或超大 ArrayBuffer(如百 MB 级图像数据)会触发同步序列化,可能卡顿;建议对大数据分块传输,或使用
transferable选项(如postMessage(data, [arrayBuffer]))将 ArrayBuffer 所有权移交,避免拷贝。 - 循环引用支持:StructuredClone 原生支持对象/数组内的循环引用,无需额外配置,这是它比 JSON 显著的优势。
-
兼容性兜底:旧浏览器不支持时,
postMessage会退化为较弱的结构化克隆(类似早期 JSON 行为),建议用try...catch捕获DataCloneError并降级处理。 -
Worker 初始化数据:构造
Worker时传入的options.type = 'module'不影响克隆逻辑,但模块脚本中的顶层export仍需通过postMessage传递,不能直接共享。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











