返回

浅尝止步还是兼容并蓄?JS基础精进之路,剖析深拷贝与浅拷贝

前端

引言

在JavaScript的世界里,对象是一个神奇的存在,它可以存储各种各样的数据,包括其他对象。当我们操作对象时,需要注意一个问题:是浅拷贝还是深拷贝?浅拷贝和深拷贝是两个不同的概念,它们会影响到对象数据的复制方式。

浅拷贝

浅拷贝是指只复制对象本身的数据,而不会复制其属性所引用的对象。也就是说,浅拷贝后的新对象只拥有原对象的属性的引用,而不是属性值本身。如果属性值是一个基本类型的数据(如字符串、数字、布尔值),那么浅拷贝后的新对象和原对象拥有相同的属性值。但是,如果属性值是一个引用类型的数据(如对象、数组),那么浅拷贝后的新对象和原对象拥有不同的属性值,因为它们指向不同的对象。

深拷贝

深拷贝是指不仅复制对象本身的数据,还会复制其属性所引用的对象。也就是说,深拷贝后的新对象不仅拥有原对象的属性的引用,还拥有属性值本身。如果属性值是一个基本类型的数据,那么深拷贝后的新对象和原对象拥有相同的属性值。如果属性值是一个引用类型的数据,那么深拷贝后的新对象和原对象拥有不同的属性值,因为它们指向不同的对象。

对象深拷贝方法

1、JSON方法

const obj = {
  name: '张三',
  age: 18,
  hobbies: ['篮球', '足球', '乒乓球']
};

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

缺点是:

  • 属性undefined无法复制
  • 属性function无法复制

2、递归

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

  if (Array.isArray(obj)) {
    const newArr = [];
    for (let i = 0; i < obj.length; i++) {
      newArr.push(deepCopy(obj[i]));
    }
    return newArr;
  }

  const newObj = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopy(obj[key]);
    }
  }
  return newObj;
}

同样适用于数组深拷贝。

3、Object.assign()

const obj = {
  name: '张三',
  age: 18,
  hobbies: ['篮球', '足球', '乒乓球']
};

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

Object.assign()方法可以将一个或多个源对象的属性复制到目标对象。它只复制源对象的自身属性,不会复制其原型属性。

选择浅拷贝还是深拷贝

在实际开发中,我们应该根据项目的需求来选择浅拷贝还是深拷贝。一般来说,如果我们只需要复制对象本身的数据,而不需要复制其属性所引用的对象,那么可以使用浅拷贝。如果我们需要复制对象及其属性所引用的对象,那么可以使用深拷贝。

结语

浅拷贝和深拷贝是JavaScript中的两个重要概念,它们可以帮助我们更好地理解和操作对象。在实际开发中,我们应该根据项目的需求来选择浅拷贝还是深拷贝。