返回

JS常见拷贝方法:深入浅出解析浅拷贝、深拷贝与结构拷贝

前端

浅拷贝

浅拷贝是指只拷贝对象或数组的第一层属性,而不会递归地拷贝嵌套的对象和数组。

浅拷贝方法

  • Object.assign():Object.assign()方法可以将一个或多个源对象的属性拷贝到目标对象。它只会拷贝源对象的浅层属性,不会递归地拷贝嵌套的对象和数组。

  • 扩展运算符(...):扩展运算符(...)可以将一个对象或数组的属性拷贝到另一个对象或数组中。它只会拷贝浅层属性,不会递归地拷贝嵌套的对象和数组。

浅拷贝示例

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

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

console.log(obj2);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }

const obj3 = { ...obj1 };

console.log(obj3);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }

在上面的示例中,我们使用Object.assign()方法和扩展运算符(...)对obj1对象进行了浅拷贝。可以看到,obj2和obj3都是obj1的浅拷贝,它们都具有与obj1相同的浅层属性。但是,obj2和obj3的address属性指向的是同一个对象,这意味着对obj2或obj3的address属性所做的任何更改都会反映在另一个对象上。

深拷贝

深拷贝是指递归地拷贝对象或数组的所有属性,包括嵌套的对象和数组。

深拷贝方法

  • JSON.parse(JSON.stringify()):JSON.parse(JSON.stringify())方法可以将一个对象或数组序列化为JSON字符串,然后再将其解析回一个对象或数组。这种方法可以实现对象的深拷贝。

  • 使用递归:我们可以使用递归函数来实现对象的深拷贝。递归函数会遍历对象或数组的所有属性,并对每个属性进行深拷贝。

深拷贝示例

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

const obj2 = JSON.parse(JSON.stringify(obj1));

console.log(obj2);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }

function 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 obj3 = deepCopy(obj1);

console.log(obj3);
// 输出:{ name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }

在上面的示例中,我们使用JSON.parse(JSON.stringify())方法和递归函数实现了obj1对象的深拷贝。可以看到,obj2和obj3都是obj1的深拷贝,它们具有与obj1相同的属性,并且这些属性指向的是不同的对象。这意味着对obj2或obj3的任何属性所做的更改都不会反映在另一个对象上。

结构拷贝

结构拷贝是指只拷贝对象或数组的结构,而不拷贝其值。结构拷贝通常用于创建对象或数组的副本,以便对其进行修改,而不会影响原始对象或数组。

结构拷贝方法

  • Object.create():Object.create()方法可以创建一个新对象,该对象的原型是另一个对象。新对象具有与原型对象相同的结构,但不会拷贝原型对象的值。

  • 使用扩展运算符(...):扩展运算符(...)可以将一个对象或数组的结构拷贝到另一个对象或数组中。它只拷贝结构,不会拷贝值。

结构拷贝示例

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

const obj2 = Object.create(obj1);

console.log(obj2);
// 输出:{}

const obj3 = { ...obj1 };

console.log(obj3);
// 输出:{ name: undefined, age: undefined, address: undefined }

在上面的示例中,我们使用Object.create()方法和扩展运算符(...)对obj1对象进行了结构拷贝。可以看到,obj2和obj3都是obj1的结构拷贝,它们具有与obj1相同的结构,但没有拷贝obj1的值。这意味着对obj2或obj3的任何属性所做的更改都不会影响obj1。

总结

在JavaScript中,我们经常需要对对象和数组进行拷贝操作。拷贝方法主要分为浅拷贝、深拷贝和结构拷贝。浅拷贝只拷贝对象或数组的第一层属性,而深拷贝会递归地拷贝对象或数组的所有属性,包括嵌套的对象和数组。结构拷贝只拷贝对象或数组的结构,而不拷贝其值。

在实际开发中,我们需要根据不同的需求选择合适的拷贝方法。如果只需要拷贝对象或数组的第一层属性,那么可以使用浅拷贝方法。如果需要拷贝对象或数组的所有属性,包括嵌套的对象和数组,那么可以使用深拷贝方法。如果只需要拷贝对象或数组的结构,而不拷贝其值,那么可以使用结构拷贝方法。