JS深浅拷贝介绍与实现

深浅拷贝主要针对对象而言的。

浅拷贝:只拷贝对象最外面一层的基本数据类型的数据;若属性是对象,只拷贝其引用。
深拷贝:拷贝多层数据;每一层级别的数据都会拷贝。

深拷贝会把对象里所有的数据重新复制到新的内存空间,是最彻底的拷贝。

复制(赋值)与拷贝

赋值可以是基本数据类型和引用数据类型,拷贝是针对对象(引用数据类型)。

赋值

基本数据类型
let a=1,b=a;

操作数据的时候a,b值互不影响。b=a实际此时b与a指向同一栈地址取其存放的值,只不过b或a值发生改变后,会开辟新的栈内存存放其值,指针也相应发生改变。

引用数据类型
 const Jane={name:'Jane',age:22};
 let Jim=Jane;

Jane和Jim都指向同一堆地址(对象所在)。无论谁操作了对象的值,都会彼此影响。

拷贝

浅拷贝

会为对象第一层属性值是基本数据类型的数据开辟完整内存空间复制存放,如果值是引用类型,只是赋值其引用。
也就是说,浅拷贝的对象第一层属性值是基本类型的属性是完全独立于原始对象的,引用类型的话还是两者共享。

经典for...in实现浅拷贝

const Tom={name:'Tom',age:24,company:{name:'Tencent',addr:'SZ'}};
let Tony={}
for (let key in Tom) {
	Tony[key]=Tom[key]
}
Tony.name='Tony'
Tony.company.name='DaJiang'
console.log(Tom);
console.log(Tony);

在这里插入图片描述

深拷贝

原对象与拷贝对象属性互不影响。

🌰递归实现深拷贝

function deepColon(obj){
 let colon=Array.isArray(obj)?[]:{}
 for (let [key,value] of Object.entries(obj)) {
 	if(value&&typeof value==='object'){
		colon[key]=deepColon(value)
	}else{
		colon[key]=value;
	}
 }
 return colon;
}

更多深浅拷贝实现方法

浅拷贝

Object.assign()
// 语法1
obj2 = Object.assgin(obj2, obj1);

// 语法2
Object.assign(目标对象, 源对象1, 源对象2...);

解释:将obj1 拷贝给 obj2。执行完毕后,obj2 的值会被更新。

作用:将 obj1 的值追加到 obj2 中。如果对象里的属性名相同,会被覆盖。

从语法2中可以看出,Object.assign() 可以将多个“源对象”拷贝到“目标对象”中。

let Tom={name:'Tom',location:{nation:'CHN',city:'XX'}}
let Tony=Object.assign({},Tom,{age:24,name:'Tony'})

在这里插入图片描述

slice()

slice数组切割,不设置参数,默认从下标0开始,并返回一个新数组。如果是一维数组,那也算完全拷贝了。

const arr=[1,2,3]
let obj=arr.slice()

🌰证明slice浅拷贝

const arr=[1,2,3,[4,5]]
let obj=arr.slice()
obj[0]=0
obj[3][0]=6//不可obj[3]=6 这样是直接指向另外一个对象的地址了而不是在原对象上改变值
concat()

concat数组拼接,不设置参数,则返回原数组的一个副本。如果是一维数组,那也算完全拷贝了。

const arrA=[1,2,3,[4,5]]
let arrB=arrA.concat()
arrB[3][1]=0
console.log(arrA);
…拓展运算符

ES6拓展运算符可以实现数组浅拷贝。如果是一维数组,那也算完全拷贝了。

const a=[1,2,[1,2]]
let [...b]=a
let c=[...a]

深拷贝

通过JSON对象实现深拷贝

弊端:如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null;
如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

	const XiaoMing={name:'XiaoMing',age:22,company:{name:'Tencent',addr:'SZ'}};
	let XiaoHong=JSON.parse(JSON.stringify(XiaoMing));
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值