structuredclone是javascript原生深拷贝函数,支持map、set、date、regexp、arraybuffer等复杂类型及循环引用,但不支持function、dom节点、undefined等;需检查浏览器兼容性(chrome 98+等)并做降级处理。

structuredClone 是浏览器原生支持的深拷贝方法,不是 HTML 特性,也不需要写在 HTML 标签里——它是一个 JavaScript 全局函数,直接在 <script></script> 中调用即可。如果你在 HTML 文件里写 JS 时遇到报错、不生效或兼容性问题,核心原因通常出在运行环境或数据类型上,而不是 HTML 写法本身。
为什么在 HTML 中调用 structuredClone 报错 “not defined”?
这是最常见误解:以为要引入什么 polyfill 或 script 标签才能用。实际上:structuredClone 是全局函数,像 console.log 一样开箱即用——但仅限支持它的浏览器。
- Chrome 98+、Firefox 97+、Safari 15.4+ 原生可用;Edge 101+ 同步支持
- 旧版 Safari(如 15.3 及更早)、IE、部分安卓 WebView 会直接抛出
ReferenceError: structuredClone is not defined - Node.js 环境(包括 20.0+)默认不提供该 API,需显式启用
--experimental-structured-cloning或用node:worker_threads的transferList模拟
判断是否可用,直接加一行防御性检查:
if (typeof structuredClone === 'function') {
const clone = structuredClone(original);
} else {
// 降级方案,例如 JSON.parse(JSON.stringify(original))
}
structuredClone 在 HTML 页面中处理 DOM 数据时的限制
很多人尝试对 document.querySelector('input') 或 event.target 这类 DOM 节点调用 structuredClone,结果得到 DataCloneError。这不是 bug,是规范明确禁止的。
-
structuredClone不支持克隆HTMLElement、Document、window、document、location等宿主对象 - 它只处理“可结构化克隆”的值:基本类型、
Array、Object、Map、Set、Date、RegExp、ArrayBuffer、Blob、File、Error、ImageData等 - 若你真想“复制表单状态”,应提取其
value、checked、selectedOptions等可序列化属性,再传给structuredClone
如何在 HTML 页面中安全使用 structuredClone 处理用户输入或状态数据?
典型场景是保存表单快照、还原编辑前状态、或跨 postMessage 传递配置。关键在于「只传纯数据,不传引用」。
- 避免直接传
this、event、localStorage返回的原始值(某些旧版 Safari 对localStorage.getItem返回的字符串调用structuredClone会静默失败) - 对含
undefined、function、Symbol(非Symbol.for)、WeakMap的对象,structuredClone会抛DataCloneError;建议提前清洗或用try/catch包裹 - 若数据含
ArrayBuffer且需零拷贝转移(比如大图处理),可配合{ transfer: [buf] }选项,但注意:转移后原buf将变为detached,不可再读写
示例:安全克隆表单数据
const form = document.getElementById('myForm');
const data = Object.fromEntries(new FormData(form));
// data 是 plain object,不含 DOM 引用,可安全克隆
const snapshot = structuredClone(data);
为什么用了 structuredClone 还是发现修改副本影响了原对象?
大概率是你克隆的对象里混入了不被支持的类型,导致克隆中途失败,返回的其实是浅拷贝或未定义行为。尤其注意以下三类“隐形陷阱”:
-
Proxy对象:即使内部是普通对象,structuredClone也无法克隆,会抛错或静默跳过 - 带
getter/setter的对象属性:getter 不执行,setter 不绑定,克隆后只是静态值快照 - 自定义类实例(如
new MyClass()):除非它可被结构化克隆算法识别(比如继承自Error或Date),否则会被当作普通对象处理,原型链丢失
真正可靠的深拷贝,前提是数据本身“干净”——没有函数、无循环引用(虽然它支持,但调试时容易忽略)、不含宿主对象。一旦越界,就别指望一行 structuredClone 解决所有问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











