返回

浅拷贝&深拷贝

前端

浅拷贝和深拷贝的原理

在JavaScript中,对象是一种引用类型,这意味着对象本身在内存中存储的是一个地址,指向实际存储对象数据的位置。当我们对对象进行赋值时,实际上是复制了这个地址,而不是复制对象本身。因此,如果我们修改了对象的属性,那么所有指向该对象的变量都会受到影响。

浅拷贝和深拷贝都是为了解决这个问题而产生的。浅拷贝只复制对象的属性,而深拷贝则复制对象的所有属性及其嵌套对象。

浅拷贝可以通过Object.assign()方法实现,如下所示:

const obj1 = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "Anytown",
    state: "CA",
  },
};

const obj2 = Object.assign({}, obj1);

obj2.name = "Jane Doe";

console.log(obj1); // { name: "John Doe", age: 30, address: { street: "123 Main Street", city: "Anytown", state: "CA" } }
console.log(obj2); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Anytown", state: "CA" } }

在上面的示例中,我们首先创建了一个对象obj1,然后使用Object.assign()方法创建了一个新对象obj2,并将obj1作为参数传递给该方法。Object.assign()方法将obj1的所有属性复制到obj2中,包括嵌套对象address。

因此,当我们修改obj2的name属性时,obj1的name属性不会受到影响。这是因为Object.assign()方法只复制了对象的属性,而不是复制对象本身。

深拷贝可以通过递归实现,如下所示:

function deepCopy(obj) {
  if (typeof obj !== "object" || obj === null) {
    return obj;
  }

  const newObj = {};

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

  return newObj;
}

const obj1 = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "Anytown",
    state: "CA",
  },
};

const obj2 = deepCopy(obj1);

obj2.name = "Jane Doe";

console.log(obj1); // { name: "John Doe", age: 30, address: { street: "123 Main Street", city: "Anytown", state: "CA" } }
console.log(obj2); // { name: "Jane Doe", age: 30, address: { street: "123 Main Street", city: "Anytown", state: "CA" } }

在上面的示例中,我们首先创建了一个名为deepCopy()的函数,用于对对象进行深拷贝。该函数首先检查obj是否是对象,如果不是,则直接返回obj。如果obj是对象,则创建一个新的对象newObj。然后,该函数遍历obj的所有属性,并使用deepCopy()函数对每个属性进行深拷贝。最后,该函数将newObj返回。

因此,当我们修改obj2的name属性时,obj1的name属性不会受到影响。这是因为deepCopy()函数复制了对象的所有属性及其嵌套对象。

浅拷贝和深拷贝的区别

浅拷贝和深拷贝的区别在于,浅拷贝只复制对象的属性,而深拷贝则复制对象的所有属性及其嵌套对象。浅拷贝可以通过Object.assign()方法实现,而深拷贝可以通过递归实现。

浅拷贝和深拷贝的优缺点如下:

特性 浅拷贝 深拷贝
速度
内存占用
适用场景 对象属性简单,不包含嵌套对象 对象属性复杂,包含嵌套对象

浅拷贝和深拷贝的应用场景

浅拷贝和深拷贝在不同的场景下有不同的应用。浅拷贝通常用于复制简单对象,例如只包含基本数据类型的对象。深拷贝通常用于复制复杂对象,例如包含嵌套对象或数组的对象。

以下是一些浅拷贝和深拷贝的具体应用场景:

  • 浅拷贝:
    • 复制表单数据
    • 复制查询参数
    • 复制配置对象
  • 深拷贝:
    • 复制对象作为函数参数
    • 复制对象到另一个对象
    • 复制对象到数组中
    • 复制对象到集合中

结论

浅拷贝和深拷贝都是JavaScript中常用的技术,用于复制对象。浅拷贝只复制对象的属性,而深拷贝则复制对象的所有属性及其嵌套对象。两种技术各有优缺点,在不同的场景下有不同的应用。了解浅拷贝和深拷贝的原理、区别和应用场景,可以帮助您更好地理解和使用它们。