解构和展开做的是浅拷贝吗?structuredClone 能替代手写深拷贝吗?

先理解原理和示例,再练习完整口述与追问。

对象展开、数组展开、Object.assign 和解构只复制一层,嵌套对象仍是同一引用。structuredClone 能克隆多数内置结构、循环引用和 Map/Set,不能克隆函数、DOM 节点、类实例的方法,也不会走访问器以外的自定义克隆协议。深拷贝方案要按数据种类选择,见通用题 12 和手写题里的深拷贝。

{ ...obj } 和 Object.assign({}, obj) 只复制源对象自己的可枚举字符串键,值按引用复制。数组 slice、concat、展开也一样。解构 const { profile } = user 只是取出 profile 这个引用,改 profile.city 就是改原对象。默认值同样只在取值是 undefined 时使用。

structuredClone 使用结构化克隆算法:可以处理普通对象、数组、Date、RegExp、Map、Set、ArrayBuffer、Blob,以及循环引用,并且默认克隆而不是共享这些内置容器。它不能克隆函数、Symbol 键、DOM 节点,遇到它们会抛 DataCloneError。类实例会被克隆成普通对象,原型和方法不会保留。访问器会被读成当前值,再存成数据属性。

js
const user = { name: 'Ada', profile: { city: 'HZ' } }
const copy = { ...user }
copy.profile.city = 'SH'
console.log(user.profile.city) // 'SH'

const box = { self: null, date: new Date(0) }
box.self = box
const cloned = structuredClone(box)
console.log(cloned.self === cloned, cloned.date.getTime(), cloned.date !== box.date) // true 0 true
structuredClone({ fn() {} }) // DataCloneError

JSON.parse(JSON.stringify(obj)) 会丢掉 undefined、函数、Symbol,Date 变字符串,Map 变空对象,循环引用直接抛错。它只适合协议已经限制成纯 JSON 的数据。解构重命名和默认值不会做深拷贝。

展开、Object.assign、slice 和解构都是浅复制,嵌套对象改一处两边都能看到。structuredClone 能克隆 Date、Map、Set、ArrayBuffer 和循环引用,适合把一份纯数据彻底拆开。它不能克隆函数和 DOM 节点,类实例也会丢掉原型。有函数、需要保留类,或者要控制哪些字段复制时,仍要按通用题里的深拷贝规则自己写。