浅谈深拷贝与浅拷贝

一、拷贝(克隆)的意义的场景

意义:保证原数据的完整性和独立性
常见场景:复制数据、函数入参、class构造函数

二、浅拷贝

  • 只克隆对象的第一层级
  • 如果属性值是原始数据类型,拷贝其值,即:值拷贝
  • 如果属性值是引用类型,拷贝其内存地址,即:引用拷贝

1、ES6拓展运算符 … / slice(0) / [ ].concat

const sourceObject = { foo: [1, 2, 3], bar: { x: 10, y: 20 } };
const copiedObject = { ...sourceObject };

copiedObject.foo.push(4);
copiedObject.bar.z = 30;

console.log(sourceObject.foo); // Output: [1, 2, 3, 4] (原对象也被修改)
console.log(sourceObject.bar); // Output: { x: 10, y: 20, z: 30 } (原对象也被修改)

// 数组的浅拷贝
const arr = [1, 2, 3]
const arr2 = [...arr]
const arr3 = arr.slice(0)
const arr4 = [].concat(arr)

2、Object.assign()

const target = {};

const source1 = { foo: 1 };
const source2 = { bar: 2, aaa: {bbb: 666}};

Object.assign(target, source1, source2);

3、for…in…和其它的一层遍历复制

const source = { foo: 1, bar: 2 };
const target = {};

for (const key in source) {
  target[key] = source[key];
}

console.log(target);
// Output: { foo: 1, bar: 2 }

const source = { foo: 1, bar: 2 };
const target = {};

for (const key in source) {
  if (source.hasOwnProperty(key)) {
    target[key] = source[key];
  }
}

console.log(target);
// Output: { foo: 1, bar: 2 }

这样可以确保只复制对象自身的属性,而不包括继承的属性。

需要注意的是,for...in 循环不会复制对象的方法,只会复制属性。
如果要复制对象的方法,可以使用其他方法或库来实现更复杂的拷贝,比如深拷贝。

三、深拷贝

  • 克隆对象的每个层级
  • 如果属性值是原始数据类型,拷贝其值,即:值拷贝
  • 如果属性值是引用类型,递归克隆

1、JSON.parse(JSON.stringify( obj ))

  • 只能复制普通键的属性,Symbol类型的无能为力
  • 循环引用对象,比如 window无法复制
  • 函数 Date Rege Blob等类型不能复制
  • 性能差
function clone(obj) {
	return JSON.parse(JSON.stringify(obj))
}
const a = clone({
	a: 1,
	b: { c: 2 }
})
console.log('a:', a)

// 时间: 转为字符串
console.log('date:', clone({date:new Date()}))

// 正则: 变成空对象   异常
console.log('regex:', clone({regex:/[0-9]/}))

// Blob: 变成空对象   异常
console.log('blob:', clone({blob:new Blob(['123'])}))

// 函数
console.log('function:', clone({fn(){}})) // {}

// window
console.log('function:', clone(window)) // Uncaught TypeError: Converting circular structure to JSON

在这里插入图片描述

2、消息通讯BroadcastChannel

  • 循环引用对象不能复制, 如 window
  • 函数不能复制
  • 同步变成异步
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

3、手写简单版深拷贝

在这里插入图片描述
上面的方法 如果在数组中添加了非数字属性就会出问题

在这里插入图片描述

在这里插入图片描述

4、浅拷贝 vs 深拷贝

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

老电影故事

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

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

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

打赏作者

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

抵扣说明:

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

余额充值