浅谈JS中对象的浅复制和深复制

基础知识:
JS对象:指向内存中某个位置的指针,指针是可变的,也就是说可以被重新赋值,所以说,复制指针,只是将两个指针指向内存中的同一地址,也可以说是地址复制。

//复制指针
var obj = { a: "123" };
var newObj = obj;

在上面代码中,对象 obj和 newObj都能随着对方的变化而变化,所以要根据实际情况来复制对象。

一、浅复制
如果要操作的对象拥有的属性都是值类型,那么可以使用扩展语法或 Object.assign()

var obj = { foo: "foo", bar: "bar" };
var newObj = { ...obj };   // Object { foo: "foo", bar: "bar" }
var newObj = Object.assign({}, obj);    // Object { foo: "foo", bar: "bar" }

补充知识:Object.assign()是ES6新加的接口,主要用来合并多个JS对象

  1. Object.assign() 第一个参数是目标对象,后面的都是源对象。 Object.assign (target, source1,source2, source3, …);
  2. 如果源对象与目标对象有相同的属性名,或源对象中有相同的属性名,后面的会覆盖前边的值
  3. 如果参数传入的不是Object,会转成Object
  4. null和undefined 不能作为参数传入,因为null和undefined 不能转成Object
  5. 如果发生的值是一个对象,Object.assign的处理方法是直接替换,而不是添加

Object.assign()内容详情可查看:MDN中对Object.assign()的描述

一个小细节注意一下:从使用效果上来看,Object.create()创建的新对象有点类似浅复制,只不过新对象和原对象是一种继承关系,而Object.assign()创建的新对象和原对象是彼此独立的。

var obj = { a: "123", b: { c: "321"}};
for(let p in obj){
	newObj[p] = obj[p];
}

上述代码只进行了对对象第一层的复制,对象里引用类型则进行的是地址复制,这一操作也是浅复制

二、深复制
1、有限制的深复制(先把对象序列化为字符串,然后再将其反序列化)

var obj = { a: "123", b: "321"};
var newObj = JSON.parse(JSON.srtingify(obj));

限制:只在对象中包含可系列化值,且没有循环引用的情况下使用
日期对象不可以被序列化,JSON.parse()后为字符串而不是日期

2、限制较少的深复制(使用递归思想)

function deepCopy(obj){
	var newObj = {};
	for(let p in obj){
		if(!(p instanceof object) || (typeof p === 'function)){
			newObj[p] = objt[p];
		}else{
			newObj[p] = deepCopy(obj[p]);
		}
	}
	return newObj;
}

所以可以得出一种较为通用的JS复制对象的方法:

function deepCopy(obj){
	var newObj =obj.constructor === Array ? [] : {};
	newObj.constructor = obj.constructor;
	if(typeof obj !== 'object'){
		return ;
	}else if(window.JSON) {  //若需考虑特殊数据类型,比如正则函数等,则去掉此else if
		newObj = JSON.parse(JSON.stringify(obj));
	}else {
		for(let p in obj){
			if(obj[p].constructor === regExp || obj[p].constructor === Date){
				newObj[p] = obj[p];
			}else if(typeof p === 'object'){
				newObj[p] = deepCopy(obj[p]);
			}else{
				newObj[p] = obj[p];
			}
		}
	}
	return newObj;
}

学习参考:
https://segmentfault.com/a/1190000018903274#articleHeader1
https://baijiahao.baidu.com/s?id=1625060204489718788&wfr=spider&for=pc

这是我第一次写学习总结文章,若有不对的地方,麻烦大佬们指出错误,我们共同进步呀~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值