返回

剖析深拷贝:前端面试的高频叩问,不仅考察技术更考验思维

前端

在前端面试中,深拷贝可谓是高频问题,也是一道基础题。所谓的基础不是说深拷贝本身是一个非常简单、非常基础的问题,而是面试官要通过深拷贝来考察候选人的JavaScript基础,甚至是程序设计能力。

我们知道在 JavaScript 中存在“引用类型“和“值类型“的概念。因为“引用类型“在内存中是通过地址来存储的,所以当对它们进行复制时,实际上复制的只是内存地址,而不是实际的值。这就意味着,如果修改了复制后的对象的属性,那么原始对象也会受到影响。这就是我们所说的浅拷贝。

深拷贝与浅拷贝的区别在于,深拷贝会复制对象及其所有属性的副本,这样对副本所做的任何修改都不会影响原始对象。

在 JavaScript 中,可以使用多种方法来实现深拷贝。最常见的方法是使用 JSON.parse() 和 JSON.stringify() 函数。JSON.stringify() 函数将对象转换为 JSON 字符串,而 JSON.parse() 函数将 JSON 字符串转换为对象。通过这种方式,就可以实现深拷贝。

例如,以下代码演示了如何使用 JSON.parse() 和 JSON.stringify() 函数实现深拷贝:

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

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

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

console.log(originalObject);
// {
//   name: 'John Doe',
//   age: 30,
//   address: {
//     street: '123 Main Street',
//     city: 'Anytown',
//     state: 'CA',
//     zip: '12345'
//   }
// }

console.log(deepCopy);
// {
//   name: 'John Doe',
//   age: 30,
//   address: {
//     street: '456 Elm Street',
//     city: 'Anytown',
//     state: 'CA',
//     zip: '12345'
//   }
// }

如上所示,修改 deepCopy 对象的属性不会影响 originalObject 对象。

除了 JSON.parse() 和 JSON.stringify() 函数之外,还可以使用递归函数来实现深拷贝。递归函数可以通过不断地调用自身来遍历对象及其所有属性,并逐一复制这些属性的值。

例如,以下代码演示了如何使用递归函数实现深拷贝:

function deepCopy(obj) {
  if (typeof obj === 'object' && obj !== null) {
    const newObj = Array.isArray(obj) ? [] : {};
    for (const key in obj) {
      newObj[key] = deepCopy(obj[key]);
    }
    return newObj;
  } else {
    return obj;
  }
}

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

const deepCopy = deepCopy(originalObject);

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

console.log(originalObject);
// {
//   name: 'John Doe',
//   age: 30,
//   address: {
//     street: '123 Main Street',
//     city: 'Anytown',
//     state: 'CA',
//     zip: '12345'
//   }
// }

console.log(deepCopy);
// {
//   name: 'John Doe',
//   age: 30,
//   address: {
//     street: '456 Elm Street',
//     city: 'Anytown',
//     state: 'CA',
//     zip: '12345'
//   }
// }

如上所示,修改 deepCopy 对象的属性不会影响 originalObject 对象。

无论是使用 JSON.parse() 和 JSON.stringify() 函数还是使用递归函数,都可以实现深拷贝。选择哪种方法取决于具体情况。如果对象比较简单,可以使用 JSON.parse() 和 JSON.stringify() 函数。如果对象比较复杂,则可以使用递归函数。

深拷贝在前端开发中有着广泛的应用场景。例如,在需要将对象传递给另一个函数并对其进行修改时,可以使用深拷贝来确保原始对象不受影响。又或者,在需要将对象存储到本地存储或数据库中时,可以使用深拷贝来确保存储的对象是对象的副本,而不是对象的引用。

总之,深拷贝是一个非常重要的 JavaScript 知识点。掌握深拷贝的概念和实现方法,可以帮助我们在前端开发中编写出更加健壮、可靠的代码。