JavaScript spread operator克隆对象后深层属性被修改该如何解决?
现象背后的逻辑
你遇到的是JavaScript浅拷贝的典型特征:
JavaScript中的扩展运算符...执行的是浅拷贝逻辑,仅会复制对象的第一层属性:
如果属性值是基础类型(数字、字符串、布尔值等),会直接复制值本身;如果属性值是引用类型(对象、数组等),只会复制该引用对应的内存地址,不会递归复制嵌套的引用类型实体。
对应你提供的代码,const obj1 = { ...obj }执行完成后,obj.c和obj1.c指向的是内存中的同一个对象,因此你修改obj.c.p = 5时,两个引用访问到的是同一个对象的属性,最终console.log(obj1.c.p)输出5。
如何实现输出3
你需要对原对象做深拷贝,让obj1的嵌套属性c指向完全独立的新对象,修改原对象的嵌套属性不会影响到拷贝后的对象,常用实现方案如下:
- 方案1:嵌套扩展运算符,适合层级少、结构明确的场景
const obj1 = { ...obj, c: { ...obj.c } }
- 方案2:使用JS内置的
structuredCloneAPI,支持绝大多数常规JS内置类型,适配大多数深拷贝场景
const obj1 = structuredClone(obj)
- 方案3:JSON序列化+反序列化,实现简单但有局限性,无法处理函数、Symbol、循环引用等特殊场景
const obj1 = JSON.parse(JSON.stringify(obj))
内容的提问来源于stack exchange,提问作者Debug_logger
相关产品推荐
相关产品推荐

