structuredclone 对原始类型是深拷贝而非共享,因其值不可变且在目标线程堆内存中新建独立副本;symbol 不可克隆,undefined 和 bigint 在现代环境支持良好。

原始类型(如 number、string、boolean、null、undefined、symbol、bigint)在 Web Worker 的 postMessage 中,会被结构化克隆算法完整复制一份,而不是传递引用或指针。
为什么说“复制”而不是“共享”
原始类型本身不可变,且在内存中以值形式直接存储。结构化克隆时,引擎会读取其当前值,再在目标线程(Worker 或主线程)的堆内存中新建一个完全独立的副本。两个线程各自持有一份数据,互不影响。
- 修改主线程里的数字变量,Worker 收到的值不会变
- Worker 修改它收到的字符串,主线程原字符串保持不变
- 即使传的是
123或"hello"这种字面量,也照样走克隆流程——只是这个过程极快,几乎无感知
和对象/数组的区别在哪
结构化克隆对原始类型和引用类型处理逻辑一致:都要求可序列化、禁止循环引用、不保留函数或原型链。但关键差异在于结果:
- 原始类型克隆后仍是原始类型,语义清晰、行为确定
- 对象或数组会被深拷贝成新对象,但内部嵌套的原始值同样被逐个复制
- 没有“浅克隆”概念——结构化克隆天生就是深度的,只不过原始值的“深度”只有 1 层
有没有例外或边界情况
绝大多数原始类型都按预期工作,但有两个细节值得注意:
symbol无法被结构化克隆,传过去会报DataCloneError;它本质上是不可序列化的唯一标识符undefined可以传递,但在某些旧版浏览器或特定上下文中可能被静默丢弃(现代环境如 Chrome/Firefox/Edge 均支持)bigint自 ES2020 起被纳入结构化克隆标准,只要运行环境支持 BigInt,就能安全传输
实际写代码时不用特别处理
你不需要为原始类型做额外优化——它们本来就不占内存、不引发 GC 压力、复制开销微乎其微。真正需要关注性能的,是大数组、TypedArray、ImageBitmap 或 JSON 序列化成本高的对象。这时候才轮到 transferList 参数登场,把 ArrayBuffer 等可转移对象“移交”所有权,避免拷贝。











