了解JS中关于数组和对象的浅拷贝和深拷贝(深度克隆)

关于数组和对象的浅拷贝和深拷贝

数组和对象的浅拷贝和深拷贝

浅拷贝
拷贝的是引用(地址值),修改拷贝后的数据会影响原数据,使得原数据不安全
深拷贝(深度克隆):
拷贝的时候生成新数据,修改拷贝后的数据会影响原数据

浅拷贝举例:


	//直接赋值
	let user={name:"Jack",age:15};
	let user1=user;
	user1.age=18;
	//会影响原数据
	console.log(user.age);  			 //18												 
	//拷贝的是地址值
	console.log(user.age==user1.age);    //true
	
	
	//Object.assgic方法
	let user2=Object.assign(user);
	user2.name="Tom";
	//会影响原数据
	console.log(user.name);    		    //"Tom"											
	//拷贝的是地址值
	console.log(user.name==user2.name); //true										
	
	
	//Array.prototype.concat方法
	user=[1,5,{name:"Lily",age:18}];
	user1=user.concat();
	user1[0]=3;
	//user1[2]仍然拷贝的是一个地址值
	user1[2].age=20;
	//不会影响数据
	//因为Array.prototype.concat()返回的是一个新的数组
	console.log(user[0]); //1			
	//false  "1==3" 													
	console.log(user[0]==user1[0],`${user[0]}==${user1[0]}`); 
				
	//会影响原数据 
	console.log(user[2].age);  //20
	//true "20==20"
	console.log(user[2].age==user1[2].age,`${user[2].age}==${user1[2].age}`);  	
	
	
	//Array.prototype.slice方法
	user2=user.slice();
	user2[0]="abc";
	//user2[2]仍然拷贝的是一个地址值
	user2[2].name="Tom";
	//不会影响数据
	//因为Array.prototype.slice()返回的是一个新的数组
	console.log(user[0]); 							//1		
	//false   "1==abc"  													
	console.log(user[0]==user2[0],`${user[0]}==${user2[0]}`);  
				
	//会影响原数据
	console.log(user[2].name);  					//Tom		
	//true   "Tom==Tom"									
	console.log(user[2].name==user2[2].name,`${user[2].name}==${user2[2].name}`); 
	

上例中调用了Array.prototype.concat(),Array.prototype.slice() 。数组中包含一个带有name和age的对象,这个对象是一个引用类型。保存的仍然是地址值。

解决这个办法,就需要深拷贝,也就是深度克隆

满足拷贝的时候生成新数据,修改新数据不会影响原数据

1.JSON.parse(JSON.stringify())
原理是通过JSON.stringify()将js对象/js数组。转换成字符串类型的json对象/数组。


	let user=[1,5,{name:"Tom",age:18}];
	
	//JSON.parse(JSON.stringify()) 深度克隆
	let user3=JSON.parse(JSON.stringify(user));
	user3[0]=68;
	user3[2].name="lisi";
	
	console.log(user[0]);  		//1;
	console.log(user[2].name);  //Tom
	
	//false   "1==68"
	console.log(user[0]==user3[0],`${user[0]}==${user3[0]}`);      
	//false   "Tom==lisi"            
	console.log(user[2].name==user3[2].name,`${user[2].name}==${user3[2].name}`);  
	
	
	//拿到基本数据类型,再复制。就是深拷贝
	//JSON.stringify 返回的是字符串类型
	let test=JSON.stringify(user);
	console.log(typeof test);		//string	
											

2.将数组或对象的每一项都拿到基本数据类型,再复制。就是深拷贝。可通过Object.prototype.tostring.call()和for…in

Object.prototype.tostring.call() 得到数据类型

for…in 拿到数组或对象的每一项

举例:


	function checkedType(target)
	{
		//得到数据类型
		return Object.prototype.toString.call(target).slice(8,-1);
	}
	
	function clone(target)
	{
		let res,targetType=checkedType(target);
		
		if(targetType==="Object")
		{
			res={};
		}
		else if(targetType==="Array")
		{
			res=[];
		}
		else{
			return target;
		}
		//拿到数组或对象的每一项
		for (let i in target) {
			let value=target[i];
			if((checkedType(value)==="Object")||(checkedType(value)==="Array"))
			{
				 res[i]=clone(value);
			}
			else{
				 res[i]=value;
			}
		}
		return res;
		
	}

	
	let arr=[2,4,{name:"tom",age:13,color:["blue","pink","green"]}];
	let arr1=clone(arr);
	arr1[2].color[1]="red";
	arr1[1]=5;
	
	
	//false
	console.log(arr1[1]===arr[1]); 
	//false
	console.log(arr1[2].color[1]===arr[2].color[1]); 
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值