Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝

浅拷贝与深拷贝

JS数据类型

首先我们要先了解JS的数据类型,JS数据类型分为"基本数据类型"和"引用数据类型",如下标

基本数据类型引用数据类型
number常用(Obkect,Function)
string
boolean
undefined
null
symbol(ES6新增)
BigInt(ES10新增)
内存

然后我们继续了解内存,基本上所有编程语言的内存分区都是一样的.注意,我这里说的是基本上,这里是我的理解,大家不要误解啊.
内存是用来存储数据的,不同类型的数据需要存储在不同的区域
其中,
基本数据类型的变量名和值都存储在栈内存中,例如:

var name = "zhangsan"
var age = 20

在这里插入图片描述

引用数据类型的变量名存储在栈内存中,值存储在堆内存中(堆内存中会提供一个引用地址指向堆内存中的值,而这个地址是储存在栈内存中的),例如:

var hobby = ['吃饭','睡觉','打豆豆']

在这里插入图片描述
接下来我们就可以谈谈浅拷贝与深拷贝了

浅拷贝

我的理解为赋值的时候就是在拷贝
基本类型:

var a=10;
var b=a;   //b=10

在这里插入图片描述
引用类型:

var arr1=[1,2,3,4,5,6]
var arr2=arr1
console.log('arr1',arr1)
console.log('arr2',arr2)

在这里插入图片描述
此时输出结果为
在这里插入图片描述

当我们修改arr2中的数据的时候arr1中的数据也会发生变化,因为这是直接将arr1的数据的地址赋值给了arr2

var arr1=[1,2,3,4,5,6]
var arr2=arr1
arr2[0]=10    //修改arr2中的数据
console.log('arr1',arr1)
console.log('arr2',arr2)

此时输出结果为下图
在这里插入图片描述

深拷贝
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			var person={
				name:'张三',
				sex:'男',
				age:40,
				hobby:['吃饭','睡觉','打豆豆'],
				children:[
					{
						name:'张大炮',
						sex:'男',
						age:17,
						hobby:['打游戏','听歌']
					},
					{
						name:'张如意',
						sex:'女',
						age:15,
						hobby:['学习','跳舞']
					},
				]
			}
			
			// 深拷贝
			var person2={}
			for(var key in person){
				if(typeof person[key]=='object'){
					person2[key]=[];
					for(let i in person[key]){
						person2[key][i]=person[key][i]
					}
				}else{
					person2[key]=person[key]
				}
			}
			console.log('person',person)
			console.log('person2',person2)
		</script>
	</body>
</html>

此时输出结果为下图
在这里插入图片描述
然后我们将person2中的数据进行修改,然后重新输出person和person2

person2.age=20

此时结果为如下图所示,
在这里插入图片描述
可以看到,此时我们修改person2的时候person中的数据不会受到影响,可以说这就是深拷贝了(我的理解)

使用递归的方法实现深拷贝

由于直接进行深拷贝的时候,会一直嵌套,代码量有可能会变得特别大,然后用递归的方法实现深拷贝可以简化代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<script type="text/javascript">
			var person={
				name:'张三',
				sex:'男',
				age:40,
				hobby:['吃饭','睡觉','打豆豆'],
				children:[
					{
						name:'张大炮',
						sex:'男',
						age:17,
						hobby:['打游戏','听歌']
					},
					{
						name:'张如意',
						sex:'女',
						age:15,
						hobby:['学习','跳舞']
					},
				]
			}
			
			// 深拷贝
			// var person2={}
			// for(var key in person){
			// 	if(typeof person[key]=='object'){
			// 		person2[key]=[];
			// 		for(var i in person[key]){
			// 			person2[key][i]=person[key][i]
			// 		}
			// 	}else{
			// 		person2[key]=person[key]
			// 	}
			// }
			// person2.age=20
			// console.log('person',person)
			// console.log('person2',person2)
			
			// 使用递归实现深拷贝
			function deepcopy(object){  //这里的object是你要进行深拷贝的对象或数组
				var newObject={}  //newObject是返回的新的对象或数组
				for(var key in object){
					if(typeof object[key]=='object'){
						newObject[key]=deepcopy(object[key])
					}else{
						newObject[key]=object[key]
					}
				}
				return newObject
			}
			
			var person3=deepcopy(person)
			console.log('person',person)
			console.log('person3',person3)
		</script>
	</body>
</html>

输出结果如下图
在这里插入图片描述
此时,用递归的方法实现深拷贝就算完成了

在此,感谢您的认真观看

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你真的快乐吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值