JavaScript中对象复制导致两个对象存在关联问题

S中的对象操作,我们需要把A对象的值赋给B,修改B后,而A不受影响。
那如何要JS只将值赋给另一个对象,而不是把地址赋给另一个对象,导致改变影响源对象?

目前主要的实现方法有两种:
Object.assign(target, ...sources) // target:目标对象;sources:源对象
JSON.parse(JSON.stringify(obj))

方法1:Object.assign(target, ...sources)

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

  • 需要注意的是,
  1. assign()并不会深层复制,如果对象里还套有对象,则相关属性还是存在关联性的。
  2. Object.assign 不会在那些source对象值为 null 或 undefined 的时候抛出错误。
Object.assign()方法的Demo;
  • 可以看出,改变source2中inner的sou对象,target和source2目标对象也都被改变了,表明不可以深层复制
const target = { a: 1, b: 2 };
const source1 = { b: 4, c: 5, inner:{ sou: 9} };
const source2 = { e: 60, f: 70 };

const returnedTarget = Object.assign(target, source1,source2);
returnedTarget.inner.sou  = "change"  // 改变内部对象

console.log(target);
// expected output: { a: 1, b: 4, c: 5, inner: { sou: "change" }, e: 60, f: 70 }
console.log(source1);
// expected output: { b: 4, c: 5, inner: { sou: "change" } }
console.log(source2);
// expected output: { e: 60, f: 70 }
console.log(returnedTarget);
// expected output: { a: 1, b: 4, c: 5, inner: { sou: "change" }, e: 60, f: 70 }


方法2:JSON.parse(JSON.stringify(obj))

JSON.parse(JSON.stringify(obj)) 方法相对一般的浅复制(将地址赋给另一个对象),而方法2属于深复制。
利用JSON.stringify() 将js对象序列化成为字符串,然后通过JSON.parse()来反序列化(还原)js对象;因为字符串复制的是赋值而不是赋地址,这样就实现了对象复制且不和原对象产生关联。

  • 该方法需要注意的是:
  1. 源对象中有时间对象,转换后,时间将变成字符串格式,而不再是时间对象了。
  2. 源对象中里有RegExpError时,则序列化的结果将只得到空对象。
  3. 源对象中的属性有undefined时,该属性不会复制,会丢失。
  4. 源对象中的属性有function()时,无法复制 。
JSON.parse(JSON.stringify(obj))方法的Demo;
  • 可以看出,改变returnedTarget中inner的sou对象,也不会改变source中inner的sou对象,表明可以深层复制
const source = { b: 4, c: 5, inner:{ sou: 9} };

const returnedTarget = JSON.parse(JSON.stringify(source));
returnedTarget.inner.sou = "change"  // 改变内部对象

console.log(source);
// expected output: { b: 4, c: 5, inner: { sou: 9 } }
console.log(returnedTarget);
// expected output: { b: 4, c: 5, inner: { sou: "change" }}


猜你喜欢

转载自blog.csdn.net/aspire_cj/article/details/107416310