返回

揭秘JavaScript中深浅拷贝的奥秘:你会正确的拷贝吗?

前端

JavaScript中的拷贝操作:浅拷贝与深拷贝

在JavaScript中,拷贝操作是创建一个新对象或数组,使其包含与原始对象或数组相同的值。浅拷贝只复制原始对象或数组的第一层属性,而深拷贝则复制原始对象或数组的所有属性,包括嵌套对象和数组。

浅拷贝与深拷贝的区别

浅拷贝

浅拷贝只复制原始对象或数组的第一层属性,而不会复制嵌套对象或数组。如果嵌套对象或数组发生变化,浅拷贝的对象或数组不会受到影响。

const obj = {
  name: 'John Doe',
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

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

shallowCopy.address.street = '456 Elm Street';

console.log(obj.address.street); // 123 Main Street
console.log(shallowCopy.address.street); // 456 Elm Street

深拷贝

深拷贝复制原始对象或数组的所有属性,包括嵌套对象和数组。如果嵌套对象或数组发生变化,深拷贝的对象或数组也会受到影响。

const obj = {
  name: 'John Doe',
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

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

deepCopy.address.street = '456 Elm Street';

console.log(obj.address.street); // 123 Main Street
console.log(deepCopy.address.street); // 456 Elm Street

JavaScript中常用的拷贝方法

Object.create

Object.create()方法创建一个新对象,该对象继承自另一个对象。新对象具有与原对象相同的属性和方法,但不会影响原对象。

const obj = {
  name: 'John Doe',
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

const newObj = Object.create(obj);

newObj.address.street = '456 Elm Street';

console.log(obj.address.street); // 123 Main Street
console.log(newObj.address.street); // 456 Elm Street

Object.assign

Object.assign()方法将一个或多个源对象的属性复制到目标对象。目标对象是第一个参数,源对象是随后的参数。

const obj = {
  name: 'John Doe',
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

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

newObj.address.street = '456 Elm Street';

console.log(obj.address.street); // 123 Main Street
console.log(newObj.address.street); // 456 Elm Street

concat

concat()方法将两个或多个数组合并成一个新的数组。新数组包含所有数组的元素,不会影响原数组。

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];

const newArr = arr1.concat(arr2);

console.log(arr1); // [1, 2, 3]
console.log(arr2); // [4, 5, 6]
console.log(newArr); // [1, 2, 3, 4, 5, 6]

数组解构

数组解构是一种将数组元素提取到变量中的语法。它使用一对方括号[]和逗号分隔的变量名。

const arr = [1, 2, 3];

const [a, b, c] = arr;

console.log(a); // 1
console.log(b); // 2
console.log(c); // 3

toReversed

toReversed()方法将数组中的元素反转。它不会影响原数组。

const arr = [1, 2, 3];

const reversedArr = arr.toReversed();

console.log(arr); // [1, 2, 3]
console.log(reversedArr); // [3, 2, 1]

使用哪种拷贝方法

在选择拷贝方法时,需要考虑以下几点:

  • 拷贝的深度 :浅拷贝只复制原始对象或数组的第一层属性,而深拷贝则复制原始对象或数组的所有属性,包括嵌套对象和数组。
  • 性能 :深拷贝的性能比浅拷贝差。
  • 兼容性 :某些拷贝方法可能不适用于某些浏览器或JavaScript版本。

在大多数情况下,浅拷贝就足够了。但是,如果需要复制嵌套对象或数组,则应该使用深拷贝。

常见问题解答

1. 如何区分浅拷贝和深拷贝?

浅拷贝只复制原始对象或数组的第一层属性,而深拷贝则复制原始对象或数组的所有属性,包括嵌套对象和数组。

2. 哪种拷贝方法性能更好?

浅拷贝的性能比深拷贝好。

3. 哪种拷贝方法兼容性更好?

Object.assign()方法在所有浏览器和JavaScript版本中都受支持。

4. 如何创建深拷贝?

使用JSON.parse(JSON.stringify())方法可以创建深拷贝。

5. 何时需要使用深拷贝?

当需要复制嵌套对象或数组时,需要使用深拷贝。