深浅拷贝总结

一直在上面栽跟头,今天总结下

最常用的浅拷贝方法

浅拷贝定义: 只克隆第一级属性,如果某个属性又是一个内嵌的子对象,不会进入子对象中克隆子对象的内容。

1.Object.assign
此方法是es6新推出来的方法,目的是将所有可枚举属性的值从一个或多个源对象分配到目标对象
Object.assign(目标对象, 源对象)该方法参数可以有一个,或者是对个

  • 参数为一个时且为一个对象时,该方法会返回该对象
  • 参数为多个时,且参数都为对象,该方法会将源对象上的属性添加(重复的属性后面的对象会覆盖前面对象的属性)到目标对象。不会改变源对象。
//注意目标对象不能为null或undefined
Object.assign(null);       // TypeError: Cannot convert undefined or null to object
Object.assign(undefined);  // TypeError: Cannot convert undefined or null to object
//当参数为一个且不为对象时,会将值转换为对象返回
Object.assign(3);         // Number {3}
typeof Object.assign(3);  // "object"
//当参数不止一个时,null 和 undefined 不放第一个,即不为目标对象时,会跳过 null 和 undefined ,不报错
Object.assign(1,undefined);  // Number {1}
Object.assign({a: 1},null);  // {a: 1}
Object.assign(undefined,{a: 1});  // TypeError: Cannot convert undefined or null to object
//当为数组时,会将数组先转换为对象,将下标转换为键,然后进行对象合并
Object.assign([2,3], [5]);  // [5,3]
注意:assign 的属性拷贝是浅拷贝(踩过的深坑)

2.无意中看到一种方法,效果与assign一样,只能实现浅拷贝

let obj1 = {name: 'dandan', love: {car: '宝马', food:'西瓜'}}
let obj2 = {...obj1}
obj1 == obj2  //false
obj1.name = 'fufu'
console.log(obj1) // {name: 'fufu', love: {car: '宝马', food:'西瓜'}}
console.log(obj2)// {name: 'dandan', love: {car: '宝马', food:'西瓜'}}
obj1.love.food = '草莓'
console.log(obj1)// {name: 'fufu', love: {car: '宝马', food:'草莓'}}
console.log(obj2)// {name: 'dandan', love: {car: '宝马', food:'草莓'}}
最常用的深拷贝方法

深拷贝定义: 克隆第每一层级,如果某个属性又是一个内嵌的子对象,会进入子对象中克隆子对象的内容。

1.JSON.parse(JSON.stringify())的深拷贝
虽然这种方法可以成功实现嵌套属性的深拷贝,但是也有许多弊端。

  1. 如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式。
  2. 如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象;
  3. 如果obj里有函数,undefined,则序列化的结果会使对象的属性和属性值被情空(JSON.parse(JSON.stringify({name: function(){}, age: undefined})) ==》 {});
  4. 如果obj里有NaN、Infinity和-Infinity(正无穷和负无穷),则序列化的结果会变成null。
  5. 如果对象中存在循环引用的情况也无法正确实现深拷贝;

2.自定义对象数组深拷贝

function deepClone(obj) {
	if(typeof obj !== 'object' || obj === null) return obj 
	if(obj instanceof Date || obj instanceof RegExp) return obj
	// 不仅仅单纯的创建一个对象,而是创建一个跟obj对象相同类的对象。
	let newObj = new obj.constructor()
	for(let key in obj) {
		let val = obj[key]
		//只拷贝私有属性
		if(obj.hasOwnProperty(key)) {
			newObj[key] = deepClone(val)
		}
	}
	return newObj
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值