通俗易懂深浅拷贝的理解

要理解深浅拷贝,就要先知道js的数据类型有哪些。分为基本数据类型(string,number,undefind,null,symbol,boolean)和引用数据类型(obj,array,function)

然后为啥会有深浅拷贝,什么叫做深浅拷贝

其实通俗来讲就是定义一个变量a,然后赋值给变量b ,改变变量b看看a的值是否改变,ab的值都改了 说明是浅拷贝,b改a不改就是深拷贝。

基本数据类型以值得形式存储在栈中,操作的变量是值,而引用类型的值是存储在堆中,以地址来操作变量,也就是说,基本类型拷贝之后是重新在栈中开辟一个空间,两者不干扰,所以基本类型不分深浅拷贝。
但是引用类型分,浅拷贝就是,引用类型只是在栈中开辟了一个空间把变量名储存在了栈中,但是值存在了堆内存中不会被重新开辟,所以这两个空间指向的还是同一个地址(堆内存中的这个值)。

	let a1 = 2
	let a2 = a1
	console.log(a2) //2
	a2 = 3
	console.log(a2) //3
	console.log(a1) //2
	//这就说明了基本类型其实不分深浅拷贝

我们再来看引用类型的拷贝

	let obj1 = {
		name: 'zhangsan',
		age: 12,
		hobby:['1','2']
	}
	let obj2 = obj1
	obj2.name = 'lisi'
	console.log(obj1) 	// obj1 结果 {name: "lisi", age: 12, hobby: Array(3)}
						//age: 12
						//hobby: (3) ["1", "2"]
						//name: "lisi"
						//__proto__: Object
	console.log(obj2)	// obj2 结果 {name: "lisi", age: 12, hobby: Array(3)}
						//age: 12
						//hobby: (3) ["1", "2"]
						//name: "lisi"
						//__proto__: Object

我们让obj1赋值给obj2,发现改动了obj2的值,obj1的值同样改变了,这是因为他们虽然在栈中开辟了内存,但是指向了同一个地址,而引用类型是通过地址来操作的。
所以我们要是想深拷贝的话要这样做

以下方法完全是深拷贝

	let obj1 = {
		name: 'zhangsan',
		age: 12,
		hobby:['1','2']
	}
	let obj2 = obj1

	let obj3 = {}
	obj3.name = obj1.name
	obj3.age = obj1.age
	obj3.hobby = obj1.hobby
	obj2.name = 'lisi'
	obj2.hobby = ['1','2','3']
	console.log(obj1)
	console.log(obj2)
	console.log(obj3)

通俗易懂深浅拷贝的理解_第1张图片
当然这是一个麻烦的方法,你也可以通过递归for in来做

方法2 略微简单通过parse和stringify来做

	let obj1 = {
				name: 'zhangsan',
				age: 12,
				hobby: ['1', '2']
			}
			let obj2 = obj1
			let obj3 = {} 
			// obj3.name = obj1.name
			// obj3.age = obj1.age
			// obj3.hobby = obj1.hobby
			var deepClone = function(obj) {
				//把对象转成字符串再转成对象,缓存到返回值中
				var _obj = JSON.stringify(obj),
					objClone = JSON.parse(_obj)
				return objClone
			}
			obj3 = deepClone(obj1)
			obj2.name = 'lisi'
			obj2.hobby = ['1', '2', '3']
			console.log(obj1)
			console.log(obj2)
			console.log(obj3)

通俗易懂深浅拷贝的理解_第2张图片

你可能感兴趣的:(通俗易懂深浅拷贝的理解)