返回

深入理解JS中的浅拷贝与深拷贝:刷题打卡!

前端

概念

在JavaScript中,拷贝一般是指变量的复制过程。对于复杂类型,浅拷贝是指复制对象的引用地址的过程。如果修改了源对象的某个属性,由于引用相同,所以目标对象的属性也会被改变。

深拷贝是指完全复制一个全新的对象,修改源对象的属性不会影响目标对象。

测试

为了更好地理解浅拷贝和深拷贝的区别,我们可以编写一个简单的测试代码:

const obj = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
};

const shallowCopy = obj;
const deepCopy = JSON.parse(JSON.stringify(obj));

obj.name = 'Jane';
obj.address.street = '456 Elm St';

console.log(shallowCopy);
console.log(deepCopy);

运行这段代码,我们会看到以下结果:

{
  name: 'Jane',
  age: 30,
  address: {
    street: '456 Elm St',
    city: 'Anytown',
    state: 'CA'
  }
}
{
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
}

可以看到,浅拷贝对象shallowCopy的属性被修改了,而深拷贝对象deepCopy的属性没有被修改。这说明浅拷贝只复制了对象本身,而不复制其属性;深拷贝则会复制对象及其所有的属性,包括嵌套的对象。

实现

在JavaScript中,我们可以使用多种方法来实现浅拷贝和深拷贝。

浅拷贝

我们可以使用Object.assign()方法来实现浅拷贝。Object.assign()方法可以将一个或多个对象的属性复制到另一个对象中。例如:

const obj = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
};

const shallowCopy = Object.assign({}, obj);

shallowCopy.name = 'Jane';
shallowCopy.address.street = '456 Elm St';

console.log(obj);
console.log(shallowCopy);

运行这段代码,我们会看到以下结果:

{
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
}
{
  name: 'Jane',
  age: 30,
  address: {
    street: '456 Elm St',
    city: 'Anytown',
    state: 'CA'
  }
}

可以看到,浅拷贝对象shallowCopy的属性被修改了,而源对象obj的属性没有被修改。这说明Object.assign()方法只复制了对象本身,而不复制其属性。

深拷贝

我们可以使用JSON.parse()JSON.stringify()方法来实现深拷贝。JSON.stringify()方法可以将一个对象转换成JSON字符串,JSON.parse()方法可以将一个JSON字符串转换成对象。例如:

const obj = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
};

const deepCopy = JSON.parse(JSON.stringify(obj));

deepCopy.name = 'Jane';
deepCopy.address.street = '456 Elm St';

console.log(obj);
console.log(deepCopy);

运行这段代码,我们会看到以下结果:

{
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'Anytown',
    state: 'CA'
  }
}
{
  name: 'Jane',
  age: 30,
  address: {
    street: '456 Elm St',
    city: 'Anytown',
    state: 'CA'
  }
}

可以看到,深拷贝对象deepCopy的属性被修改了,而源对象obj的属性没有被修改。这说明JSON.parse()JSON.stringify()方法可以实现深拷贝。

总结

浅拷贝和深拷贝都是JavaScript中用于复制对象的两种方式。浅拷贝只复制对象本身,而不复制其属性;深拷贝则会复制对象及其所有的属性,包括嵌套的对象。

在实际开发中,我们可以根据需要选择使用浅拷贝或深拷贝。如果只需要复制对象本身,则可以使用浅拷贝;如果需要复制对象及其所有的属性,则可以使用深拷贝。