structuredclone 不能克隆函数和 dom 节点是规范刻意设计,因其仅支持可序列化、可安全跨线程传递的纯数据类型,如 date、map、arraybuffer 等;函数含闭包与执行逻辑,dom 节点绑定渲染上下文,二者均不可重建且存在安全隐患。

structuredClone 不能克隆函数和 DOM 节点,不是实现不完善,而是规范刻意为之——它只处理「可结构化克隆」的数据,而函数和 DOM 节点本质上不可序列化、不可安全转移。
它克隆的是“数据”,不是“行为”或“宿主环境”
structuredClone 的设计目标是跨线程(如 Worker)、跨上下文(如 postMessage)安全传递纯数据。函数包含执行逻辑、闭包变量、作用域链,这些在不同 JS 执行环境中无法一致重建;DOM 节点则绑定在特定 document、有事件监听器、样式计算状态、布局信息等,脱离当前文档树就失去意义。浏览器明确禁止克隆它们,是为了避免歧义和安全隐患。
- 函数:含 this 绑定、内部作用域、原型方法,克隆后无法保证语义一致
- DOM 节点:依赖渲染引擎上下文,克隆等于复制一个“空壳”,既无生命周期也无响应能力
- class 实例(带 getter/setter 或私有字段):structuredClone 只保留可枚举自有属性,丢弃原型、访问器、内部状态
它支持的,恰恰是那些能被完整描述和重建的值
比如 Date 对象,只需毫秒数就能无损还原;Map 和 Set 可遍历键值对重建;ArrayBuffer 可直接复制二进制内容;Blob 和 File 是底层字节流,天然适合传输。这些类型不依赖运行时环境,也不携带隐式状态。
- 支持:Date、RegExp、Map、Set、ArrayBuffer、TypedArray、Blob、File、ImageData、Error(仅属性)
- 不支持:Function、Promise、WeakMap、WeakSet、Proxy、window、document、location、history、NodeList、HTMLCollection
遇到 DOM 或函数怎么办?得换思路,而不是硬克隆
你真正需要的往往不是“复制节点本身”,而是“复制它的可读状态”。例如表单控件,应提取 value、checked、selectedOptions、files 等属性,组装成 plain object 再 structuredClone;若需复用逻辑,应把函数抽离为纯数据驱动的配置或工具函数,而非试图拷贝函数引用。
- 表单快照:取 input.value、select.selectedOptions、textarea.value、checkbox.checked
- 配置同步:用 JSON-safe 结构描述行为(如 { type: 'date-picker', min: '2026-01-01' }),而非传函数
- 跨 Worker 通信:只传 data + schema,让接收方按约定重建 UI 或逻辑
兼容性与降级要主动判断,不能默认 fallback
structuredClone 在 Chrome 98+、Firefox 94+、Node.js 17+ 已稳定支持,但 Safari 直到 16.4 才完全可用。检查存在性只是第一步,更重要的是验证输入是否在支持范围内——尤其当数据来自用户交互(如 event.target)时,必须提前剥离 DOM 引用,否则会直接抛 DATA_CLONE_ERR。
- 别写 if (!structuredClone) { … } 就完事,要加类型预检:isPlainObject(obj) && !hasDomOrFunction(obj)
- 降级方案(如 JSON.parse(JSON.stringify()))也有同样限制,且更隐蔽(Date 变字符串、Map 变 {}),不如明确报错来得可靠











