返回

深入浅出,剖析深拷贝与浅拷贝,轻松实现深拷贝方法

前端

深拷贝与浅拷贝

在JavaScript中,数据类型分为基本数据类型和引用数据类型。基本数据类型包括字符串、数字、布尔值和 undefined,这些数据类型的值直接存储在内存中。引用数据类型包括对象、数组和函数,这些数据类型的值存储在堆内存中,变量只保存指向堆内存中实际对象的引用。

浅拷贝 是指复制一个引用数据类型的值,但仅复制该值指向的对象的引用,并不复制该对象本身。因此,如果对浅拷贝后的对象进行修改,则原始对象也会受到影响。

深拷贝 是指复制一个引用数据类型的值,并复制该值指向的对象本身。因此,如果对深拷贝后的对象进行修改,则原始对象不会受到影响。

实现深拷贝的方法

实现深拷贝的方法有很多,以下列举了三种常见的方法:

1. 使用JSON.parse()和JSON.stringify()

这种方法是将对象转换为JSON字符串,然后使用JSON.parse()将其解析回对象。由于JSON.stringify()会将对象的所有属性和值都转换为字符串,因此这种方法可以实现深拷贝。

const obj = {
  name: 'John Doe',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY'
  }
};

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

deepCopy.name = 'Jane Doe';
deepCopy.address.city = 'Los Angeles';

console.log(obj); // { name: 'John Doe', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }
console.log(deepCopy); // { name: 'Jane Doe', age: 30, address: { street: 'Main Street', city: 'Los Angeles', state: 'NY' } }

2. 使用递归

这种方法是使用递归来遍历对象的所有属性,并为每个属性创建一个新的副本。

const deepCopy = (obj) => {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  }

  const newObj = {};
  for (const key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
};

const obj = {
  name: 'John Doe',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY'
  }
};

const deepCopy = deepCopy(obj);

deepCopy.name = 'Jane Doe';
deepCopy.address.city = 'Los Angeles';

console.log(obj); // { name: 'John Doe', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }
console.log(deepCopy); // { name: 'Jane Doe', age: 30, address: { street: 'Main Street', city: 'Los Angeles', state: 'NY' } }

3. 使用Object.assign()

这种方法是使用Object.assign()方法来复制一个对象。Object.assign()方法可以将一个或多个源对象的可枚举属性复制到目标对象。

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

deepCopy.name = 'Jane Doe';
deepCopy.address.city = 'Los Angeles';

console.log(obj); // { name: 'John Doe', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }
console.log(deepCopy); // { name: 'Jane Doe', age: 30, address: { street: 'Main Street', city: 'Los Angeles', state: 'NY' } }

总结

深拷贝和浅拷贝是JavaScript中两个重要的概念,理解和掌握这两个概念对于编写高质量的代码非常重要。在本文中,我们详细阐述了深拷贝与浅拷贝的概念和区别,并提供了多种实现深拷贝的方法。希望本文能帮助您深入理解和掌握这两个重要概念,并在实际开发中轻松应用深拷贝。