返回

深入浅出:JS 中深浅拷贝的奥秘

前端

手写 JS 之深浅拷贝

在前端开发中,我们经常需要对从后端传输过来的 JavaScript 数据进行拷贝操作,包括对象拷贝和数组拷贝。这些操作有助于数据对比和恢复。理解深浅拷贝的原理和区别至关重要,本文将深入浅出地为你揭开它们的奥秘。

浅拷贝

浅拷贝只拷贝一层,即只拷贝对象或数组本身,而不拷贝其嵌套的子对象或子数组。这意味着浅拷贝创建的副本与原对象或数组指向相同的内存地址,对副本的修改将同时影响原对象或数组。

深拷贝

深拷贝会递归地拷贝对象或数组的每一层,包括嵌套的子对象和子数组。这样创建的副本拥有独立的内存地址,对副本的修改不会影响原对象或数组。

手动实现深浅拷贝

我们可以通过以下方法手动实现深浅拷贝:

浅拷贝:

const shallowCopy = (obj) => {
  return {...obj};
};

深拷贝:

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',
  address: {
    street: 'Main St',
    city: 'New York',
  },
};

const shallowCopy = {...obj};
shallowCopy.address.city = 'Los Angeles';

console.log(obj.address.city); // Los Angeles

const deepCopy = deepCopy(obj);
deepCopy.address.city = 'San Francisco';

console.log(obj.address.city); // New York

总结

理解深浅拷贝的原理和区别对于有效地处理 JavaScript 数据至关重要。浅拷贝只拷贝一层,而深拷贝会递归地拷贝每一层。根据需要选择合适的拷贝方法,以避免不必要的修改和数据丢失。