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

浅拷贝与深拷贝

JS数据类型

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

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

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

var name = "zhangsan"
var age = 20

Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第1张图片

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

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

Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第2张图片
接下来我们就可以谈谈浅拷贝与深拷贝了

浅拷贝

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

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

Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第3张图片
引用类型:

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

Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第4张图片
此时输出结果为
Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第5张图片

当我们修改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)

此时输出结果为下图
Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第6张图片

深拷贝
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>

此时输出结果为下图
Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第7张图片
然后我们将person2中的数据进行修改,然后重新输出person和person2

person2.age=20

此时结果为如下图所示,
Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第8张图片
可以看到,此时我们修改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>

输出结果如下图
Web前端面试题:浅拷贝与深拷贝,并且用递归实现深拷贝_第9张图片
此时,用递归的方法实现深拷贝就算完成了

在此,感谢您的认真观看

你可能感兴趣的:(JS,WEB面试,前端,javascript,vue.js)