深拷贝和浅拷贝的理解与实现

一、深浅拷贝的区别:

浅拷贝:创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

深拷贝:将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。

简单理解:

假设B复制了A,修改A的时候,看B是否发生变化:

  • 如果B跟着也变了,说明是浅拷贝(修改堆内存中的同一个值)
  • 如果B没有改变,说明是深拷贝(修改堆内存中的不同的值)
二、实现深浅拷贝

1、浅拷贝:

<script>
	let obj = {
		a: 100,
		b: [10, 20, 30],
		c: {
			x: 10
		},
		d: /^\d+&/
	};
	
	// 1.用for循环可以实现浅拷贝
	let obj2 = {};
	for (let key in obj) {
		if (!obj.hasOwnProperty(key)) break;
		obj2[key] = obj[key];
	}
	
</script>

2、深拷贝:

<script>
	let obj = {
		a: 100,
		b: [10, 20, 30],
		c: {
			x: 10
		},
		d: /^\d+&/
	};
	
	// 1.用ES6可以实现深拷贝
	let obj2 = JSON.parse(JSON.Stringify(obj));
	//这种方式会存在一定的弊端
	// 1.对象中有正则时,会变成了空对象{}
	// 2.对象中有函数时,也会变成了空对象
	// 3.对象中有日期时,会把它变成字符类型


	// 2.用递归实现深拷贝
	function deepCopy(obj) {
		if (obj === null) return null;
		if (typeof obj !== "object") return obj;
		if (obj instanceof RegExp) {
			return new RegExp(obj);
		}
		if (obj instanceof Date) {
			return new Date(obj);
		}
		// 不直接创建空对象 目的:克隆的结果和之前保持相同的所属类
		let newObj = new obj.constructor;
		for (let key in obj) {
			if (obj.hasOwnProperty(key)) {
				newObj[key] = deepClone(obj[key]);
			}
		}
		return newObj;
	}

	// 3.比较好理解的递归写法
	function deepCopy(newobj, oldobj) {
		for (var k in oldobj) {
			// 判断属性属于那种数据类型
			var item = oldobj[k];
			if (item instanceof Array) {
				newobj[k] = [];
				deepCope(newobj[k], item)
			} else if (item instanceof Object) {
				newobj[k] = {};
				deepCope(newobj[k], item)
			} else {
				newobj[k] = item;
			}
		}
	}
	deepCopy(obj2,obj)
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值