结构化克隆Structured-Clone

结构化克隆算法是 HTML5 引入的标准,最初是为了在 Web Workers 之间传递数据。Electron 的 IPC(进程间通信)底层正是基于它,在主进程(Main)和渲染进程(Renderer)这两个不同的 V8 引擎实例之间搬运数据。它的核心目标是**在不同的 JavaScript 环境中,完美重建一个相同的 JS 对象**。

#status / growing #type / concept

[!info] related notes

结构化克隆 (Structured Clone)

一句话定义

structuredClone(value) 是浏览器和 Node.js 内建的深拷贝算法,支持多种原生类型和循环引用,最初为 Web Workers / postMessage 数据传递设计。

核心代码示例

// 基本用法
const original = {
  date: new Date('2024-01-01'),
  data: new Map([['key', 'value']]),
  pattern: /test/gi,
  buffer: new Uint8Array([1, 2, 3]),
  nested: { arr: [1, { deep: true }] }
};

const cloned = structuredClone(original);
console.log(cloned.date instanceof Date);   // true
console.log(cloned.data instanceof Map);    // true
console.log(cloned.pattern instanceof RegExp); // true

// 循环引用 — 不会报错
const circular = {};
circular.self = circular;
const clonedCircular = structuredClone(circular);
console.log(clonedCircular.self === clonedCircular); // true — 正确重建

支持的类型

类型支持备注
基本类型(string, number, boolean, null, undefined, BigInt)支持
Array, plain Object支持
Date支持克隆后仍是 Date 实例
RegExp支持克隆后仍是 RegExp 实例
Map, Set支持键和值递归克隆
ArrayBuffer, TypedArray支持
Blob, File支持浏览器环境
ImageData支持浏览器环境
循环引用支持自动处理
Error (DOMException, etc.)部分支持

不支持的类型(抛出 DataCloneError)

类型原因
Function绑定当前作用域/闭包,无法跨环境传递
DOM 节点属于渲染进程独有
Proxy无法序列化其拦截行为
WeakMap, WeakSet键是弱引用,无法确定哪些该拷贝
Symbol无法跨环境重建

与 JSON.parse/stringify 对比

const obj = {
  date: new Date(),
  regex: /test/g,
  fn: () => {},
  undef: undefined,
};

// JSON 方案
const jsonClone = JSON.parse(JSON.stringify(obj));
// { date: "2026-05-27T...", regex: {}, fn: 消失, undef: 消失 }

// structuredClone 方案
const scClone = structuredClone(obj);
// { date: Date实例, regex: RegExp实例 } — fn 和 undef 抛出错误(如在顶层)
维度JSONstructuredClone
Date变字符串保持实例
RegExp / Map / Set变空对象保持实例
undefined / Function静默忽略顶层抛错,对象内忽略
循环引用报错正确处理
性能(纯数据)更快稍慢
原型链丢失丢失(生成普通对象)
环境支持所有浏览器 / Node 17+

实际使用场景

// Web Worker 传递数据
worker.postMessage(structuredClone(largeData));

// Electron 主进程 / 渲染进程 IPC
ipcRenderer.send('data', structuredClone(state));

// 安全的快照(不会被后续修改影响)
const snapshot = structuredClone(currentState);

边界与常见误解

  • structuredClone 不保留原型链:克隆结果是普通对象,类实例上的方法会丢失。
  • 不是所有环境都有:Node.js 17+ 才支持,低版本需要 polyfill。
  • 性能:对纯数据对象,JSON.parse(JSON.stringify()) 通常更快;需要类型保持或循环引用支持时用 structuredClone
  • Electron 踩坑:IPC 发送含 Function 或 DOM 节点的数据会直接 DataCloneError,必须提前剥离。
创建于 2026/2/21 更新于 2026/5/27