深拷贝和浅拷贝有什么区别
先理解原理和示例,再练习完整口述与追问。
回答要点
展开运算符、Object.assign 只复制一层。JSON 序列化会丢失或改变部分类型,不能处理循环引用。structuredClone 支持循环引用及多种内建类型,但不能当成可复制函数、DOM 节点和任意类语义的万能工具。
先说明要支持哪些数据,再选择方案。MDN:structuredClone
原理拆解
浅拷贝创建一个新外层容器,但嵌套对象仍共享引用;深拷贝需要按数据模型递归创建,并用映射表处理环和重复引用。JSON 往返不是通用深拷贝:它丢弃或改变部分值、不能默认处理循环和 BigInt,也不保留许多对象类型。structuredClone 支持一组可结构化克隆的类型,但也不支持任意函数与 DOM,使用前要检查运行时。
示例与推演
const source = { profile: { city: 'A' } }
const shallow = { ...source }
shallow.profile.city = 'B'
console.log(source.profile.city) // B
const independent = { ...source, profile: { ...source.profile } }
independent.profile.city = 'C'
console.log(source.profile.city) // B
只修改一条已知路径时,按路径复制往往比深拷贝整棵状态更合适。
易错点
复制循环对象时应在递归前登记原对象到新对象的映射。不要为了“绝对隔离”无差别拷贝超大对象;函数、原型、访问器和二进制数据都需明确支持范围。
参考回答可直接练习口述
浅拷贝只复制第一层,嵌套对象仍共享;深拷贝则在约定范围内复制内部对象关系。JSON 序列化不能处理循环引用,函数、undefined、Date 等也会丢失或改变。支持的环境中 structuredClone 可复制循环引用和多种内建数据,但函数、DOM 节点等不支持,任意类实例的原型语义也不会完整保留。选方案前我先确认数据范围;表单草稿常按字段结构复制,比宣称万能深拷贝更可靠。