深拷贝和浅拷贝

一、浅拷贝

浅拷贝,指的是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址即浅拷贝是拷贝一层,深层次的引用类型则共享内存地址。

浅拷贝是指创建一个新对象,这个对象有着原始对象属性的副本。

在浅拷贝中,如果原始对象中的属性是引用类型数据(比如数组、对象等),那么新对象中对应的属性会复制一个指向原始对象中相同的引用。

因此,当修改新对象中的引用类型属性时,原始对象中的对应属性也会被修改。

1.1、例子一 for in

function shallowClone(obj) {
    const newObj = {};
    for(let prop in obj) {
        if(obj.hasOwnProperty(prop)){
            newObj[prop] = obj[prop];
        }
    }
    return newObj;
}

1.2、例子二 Object.assign({}, originalObj)

例如,以下代码展示了一个浅拷贝的例子:

let originalObj = {
  name: "John",
  age: 30,
  hobbies: ["reading", "traveling"]
};

let newObj = Object.assign({}, originalObj);

newObj.hobbies.push("cooking");

console.log(originalObj.hobbies); // Output: ["reading", "traveling", "cooking"]
console.log(newObj.hobbies); // Output: ["reading", "traveling", "cooking"]

在上面的代码中,我们使用Object.assign()方法创建了一个新对象newObj,该对象是originalObj的浅拷贝。

当我们修改newObjhobbies属性时,originalObj中对应的属性也被同时修改了。

这是因为newObjoriginalObj中的hobbies属性引用的是同一个数组对象。

二、深拷贝

深拷贝开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

深拷贝是指在内存中将一个对象完整复制一份,包括其所有的属性和子属性。手动实现深拷贝可以使用递归来遍历对象的每个属性和子属性,并复制它们的值到新的对象中。

当涉及到深拷贝时,以下是一个示例来手动实现 JavaScript 中的深拷贝:

function deepCopy(obj) {
  // 判断传入的参数是否为对象或数组
  if (typeof obj !== 'object' || obj === null) {
    return obj; // 如果是基本类型直接返回
  }

  let clone;

  // 根据传入的对象类型创建新的对象或数组
  if (Array.isArray(obj)) {
    clone = [];
  } else {
    clone = {};
  }

  // 遍历原对象的属性并递归进行深拷贝
  for (let key in obj) {
    if (Object.hasOwnProperty.call(obj, key)) {
      clone[key] = deepCopy(obj[key]);
    }
  }

  return clone;
}

// 示例

const obj1 = {
  name: 'John',
  age: 30,
  hobbies: ['reading', 'writing'],
  address: {
    street: '123 Main St',
    city: 'New York'
  }
};

const obj2 = deepCopy(obj1);

obj2.name = 'Jane';
obj2.hobbies.push('painting');
obj2.address.city = 'Los Angeles';

console.log(obj1); // { name: 'John', age: 30, hobbies: [ 'reading', 'writing' ], address: { street: '123 Main St', city: 'New York' } }
console.log(obj2); // { name: 'Jane', age: 30, hobbies: [ 'reading', 'writing', 'painting' ], address: { street: '123 Main St', city: 'Los Angeles' } }

在上面的示例中,deepCopy 函数用于手动实现深拷贝。通过调用 deepCopy(obj1),我们可以将 obj1 完整地复制到 obj2 中,并且对 obj2 的修改不会影响到 obj1

三、总结

JavaScript中,浅拷贝和深拷贝是两种常见的对象复制方式,它们有着不同的特点和适用场景。

3.1、浅拷贝

  • 创建一个新对象,新对象的属性值是原始对象属性的副本。
  • 如果原始对象的属性是基本数据类型(如字符串、数字、布尔值等),则直接复制属性值。
  • 如果原始对象的属性是引用类型数据(如数组、对象等),则复制的是对原始对象属性的引用。
  • 当修改新对象中的引用类型属性时,原始对象中的对应属性也会被修改。
  • 常见的浅拷贝方法包括Object.assign()、扩展运算符(...)和Array.slice()等。

3.2、深拷贝

  • 创建一个新对象,新对象的属性值是原始对象属性的完全独立副本。
  • 无论原始对象的属性是基本数据类型还是引用类型数据,都会被完全复制一份,包括嵌套的对象和数组。
  • 修改新对象中的任何属性,不会影响原始对象中对应的属性。
  • 实现深拷贝的常见方法包括递归遍历、JSON.parse(JSON.stringify())、第三方库(如LodashcloneDeep()方法)等。

选择使用浅拷贝还是深拷贝要根据具体的需求场景来决定:

  • 如果你只需要复制对象的第一层属性,并且不关心对应属性的修改是否会影响原始对象,那么浅拷贝就足够了。
  • 如果你需要完全独立的新对象,并确保对新对象的修改不会影响原始对象,那么深拷贝是更好的选择。

需要注意的是,深拷贝可能会导致性能上的损耗,特别是当对象很大或嵌套层级很深时。因此,在处理大型复杂对象时,要考虑是否真正需要深拷贝,以避免不必要的性能开销。

四、最后

本人每篇文章都是一字一句码出来,希望大佬们多提提意见。顺手来个三连击,点赞👍收藏💖关注✨。创作不易,给我打打气,加加油☕

  • 32
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小马甲丫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值