什么是深拷贝与浅拷贝(多种方法)

 浅拷贝 

        所谓浅拷贝,则其拷贝的就是数据,就比如b对象拷贝a对象,a的数据发送变化,其本质其实就是一个赋值的操作,新对象的这些属性数据就会跟旧对象公用一份,也就是说这两个对象指向同一份数据,他们指向同一份内存空间,一个改变就会都改变。

代码演示:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	</body>

	<script>
		let person = {
		  uname: '张三',
		  age: 22,
		  sex: '男',
		  arr: ['张三', '李四', '王五'],
		  obj: {
		    index: 1,
		    name: '赵六',
			st :{
				a : '1'
			}
		  },
		}
		let demo = {...person}
		console.log(demo)
		console.log(person)
		
		person.arr.push('小王')
		console.log(demo)
		console.log(person)

	</script>
</html>

深拷贝

         深拷贝是指拷贝对象的具体内容,二内存地址是自主分配的,拷贝结束之后俩个对象虽然存的值是一样的,但是内存地址不一样,即他们两个的数据存储空间地址不一样,俩个对象页互相不影响,互不干涉

代码演示:

        第一种 :JSON.parse 和 JSON.stringify搭配(有弊端,函数会被过滤)

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>深拷贝</title>
	</head>
	<body>
	</body>
	
	<script>
		// 弊端 : 无法复制函数,且函数会被过滤掉
		var a={x:1 , y : [a  = 1, b = {c : 2} ] , get(){}}
		var b=JSON.parse(JSON.stringify(a))
		console.log(a,'a')
		console.log(b,'b')
		a.x=2
		console.log(a,'a')
		console.log(b,'b')
	</script>
</html>

原理 :  JSON.stringify将数据转换成JSON数据对象,JSON.parse再将JSON数据对象转换成js数据类型对象,并且会自己去构建新的内存地址存放数据

     第二种 : jQuery 封装的方法($.extend()) , 必须先引入jquery

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>深拷贝</title>
	</head>
	<body>
	</body>
	<script src="http://code.jquery.com/jquery-latest.js"></script>  
	<script>

		let person = {
		  uname: '张三',
		  arr: ['李四', '王五'],
		  obj: {
		    index: 1,
		  },
		  say: function () {
		    console.log('hello javascript')
		  }
		}
		
		let son = {}
		// 第一个参数必须是 true
		$.extend(true, son, person) // 通过 $.extend() 方法实现深拷贝
		
		console.log(son,'son')
		console.log(person,'person')
		person.uname = '李四'
		console.log(son,'son')
		console.log(person,'person')

	</script>
</html>


        

        第三种 : 使用Object.assign() (存在弊端,只能嵌套浅层,多层就会出现浅拷贝的情况) 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>深拷贝</title>
	</head>
	<body>
	</body>
	<script src="http://code.jquery.com/jquery-latest.js"></script>  <!-- 在线引入jquery -->
	<script>
	
		
		//第三种 : 使用Object.assign() (存在弊端,只能嵌套单层 , 第二层开始就会出现浅拷贝的情况) 
		var person  = { name : '张三' ,age : 100, hobby : ['篮球' ,'rap' ,'唱跳'] }
		var son = Object.assign({} , person)
		console.log(person, 'person');
		console.log(son, 'son');
		person.hobby.splice(2 , 1)
		console.log(person, 'person');
		console.log(son, 'son');
	</script>
</html>

         第四种 : 使用递归来实现深拷贝

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>深拷贝</title>
	</head>
	<body>
	</body>

	<script>
			
		
		// 第四种 : 使用递归
		let person = {
		  uname: '张三',
		  arr: ['小明'],
		  obj: {
		    index: 1,
		  },
		  say: function () {
		    console.log('hello javascript')
		  }
		}
		let son = {}
		
		function myCopy(newObj, obj) {
		  for(let key in obj) {
		    if (obj[key] instanceof Array) {
		      newObj[key] = []
		      myCopy(newObj[key], obj[key])
		    } else if (obj[key] instanceof Object) {
		      newObj[key] = {}
		      myCopy(newObj[key], obj[key])
		    } else {
		      newObj[key] = obj[key]
		    }
		  }
		}
		
		// 调用递归函数
		myCopy(son, person)
		
		person.arr.push('小王')
		console.log(person,'person')
		console.log(son,'son')
		

	</script>
</html>

但这种方法似乎也有些问题,大家可以观察到进行拷贝后,函数的类型发生了改变,这里我感觉可能是因为函数是特殊的对象导致的,这里希望有大佬可以评论或者私信告知 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值