基本类型(字符串/数字/布尔)赋值即复制;对象是「引用」——拷贝的只是地址,改一处另一处跟着变。要得到完全独立的副本必须深拷贝:逐层递归复制数组、对象,特殊处理 Date、RegExp、Map/Set、循环引用。
JSON.parse(JSON.stringify(x)) 是「穷人版深拷贝」:一行代码但只能处理 JSON 能表示的结构,会丢失函数、undefined、Symbol,Date 变字符串、循环引用直接报错。结构化克隆 structuredClone() 是新方案,支持循环引用与大部分内置类型,也是 Vue/React 数据层的基础。
const a = { name: 'x', tags: ['js'], date: new Date(), fn: () => 1 }; // ❶ 浅拷贝只复制第一层 const shallow = { ...a }; shallow.tags.push('css'); // a.tags 也被污染(同一数组引用)! // ❷ JSON 深拷贝:能复制结构,但丢函数、Date 变字符串 const j = JSON.parse(JSON.stringify(a)); // j.fn === undefined // ❸ structuredClone:现代方案,循环引用也安全 const c = structuredClone(a); c.tags.push('css'); // a.tags 不受影响 console.log(c.date instanceof Date, c.fn); // true, undefined // ❹ 手写版核心:递归 + 哈希表解决循环引用 function clone(o, seen = new Map()) { if (o === null || typeof o !== 'object') return o; if (seen.has(o)) return seen.get(o); const out = Array.isArray(o) ? [] : {}; seen.set(o, out); for (const k in o) if (o.hasOwnProperty(k)) out[k] = clone(o[k], seen); return out; }