直接用 postmessage 或 worker.postmessage 即可,浏览器底层自动调用结构化克隆算法完成安全深拷贝;手动 clone 既无必要,还可能引入性能开销或类型失真,仅在预处理数据、兼容旧环境或非标准赋值时才需主动调用 structuredclone。

直接用 postMessage() 或 worker.postMessage() 就行,浏览器底层自动调用结构化克隆算法,无需手动深拷贝。
为什么不用自己 clone?
跨线程通信(如主线程 ↔ Worker、iframe ↔ 主页、Window ↔ SharedWorker)中,结构化克隆是默认且强制启用的机制。你传什么,对方收到的就是一个类型完整、内存隔离的新副本:
- Date、RegExp、Map、Set、ArrayBuffer、TypedArray、Blob、File 都能原样保留
- 嵌套对象和数组自动递归复制
- 循环引用不会报错,会被正确重建
- 修改接收端的数据,绝不会影响发送端的原始对象
哪些值传不过去?提前避开就行
结构化克隆有明确限制,以下类型会静默丢弃或抛出 DataCloneError:
- 函数(
function)、undefined、Symbol - DOM 节点(
div、document)、Window对象 - 带方法的 class 实例(只保留数据属性,constructor 和原型方法丢失)
-
Promise、WeakMap、WeakSet、Error(部分环境支持有限)
例如:{ name: 'Alice', fn: () => {}, file: new File(...) } 中的 fn 会被过滤掉,file 仍可正常传递。
怎么传才最稳妥?三步到位
1. 检查对象成分:确保只含可克隆类型(如 Object、Array、Date、Map、Blob 等),剔除函数、DOM 引用等
2. 直接发出去:
主线程worker.postMessage({<br> user: { id: 1, name: 'Bob' },<br> avatar: input.files[0],<br> meta: new Map([['uploaded', true]])<br>});
Worker 线程(worker.js)
self.onmessage = (e) => {<br> const { user, avatar, meta } = e.data; // 已是安全副本,可直接用<br> console.log(avatar instanceof File); // true<br>};
需要手动 structuredClone 的情况
仅当满足以下任一条件时才需主动调用:
- 你想在发送前预处理数据(比如删除敏感字段、统一日期格式)
- 你在非标准通信路径上操作(如直接赋值
iframe.contentWindow.xxx = obj,但应避免) - 兼容老环境(IE 不支持),此时优先选
structuredClone(现代环境)或lodash.cloneDeep(降级),别用JSON.parse(JSON.stringify())——它会把 Date 变字符串、丢掉 Map/Set
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











