js深拷贝和浅拷贝

201 阅读2分钟

#js数据类型

  JS分两种数据类型:

    基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值。

    引用数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)

###js基本数据类型和引用数据类型的存储方式

引用类型是存放在堆内存中的对象,变量其实是保存的在栈内存中的一个指针(保存的是堆内存中的引用地址),这个指针指向堆内存。

基本类型数据在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存中堆内存中的对象。

#1.浅拷贝

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

	<script type="text/javascript">
		//浅拷贝
		let arr1 = [0, 2, 5, 9, 1, 3]
		arr2 = arr1;
		console.log(arr1 === arr2);
		arr1[0] = 1;
		console.log(arr1, arr2)
	</script>
</html>

上面的代码运行结果如下

image.png

#####1).当修改arr1中第一个元素的值,同时arr2中的值也被修改 #####2).让arr1赋值给arr2时,浅拷贝实际上是将arr1的引用地址赋值给arr2,所以两个数组的引用是指向同一个堆内存,当修改arr1的值arr2同时被修改

#2.深拷贝

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

	<script type="text/javascript">
		//深拷贝
		function deepClone(obj) {
			let objClone = Array.isArray(obj) ? [] : {};
			if (obj && typeof obj === "object") {
				for (key in obj) {
					if (obj.hasOwnProperty(key)) {
						//判断ojb子元素是否为对象,如果是,递归复制
						if (obj[key] && typeof obj[key] === "object") {
							objClone[key] = deepClone(obj[key]);
						} else {
							//如果不是,简单复制
							objClone[key] = obj[key];
						}
					}
				}
			}
			return objClone;
		}
		let a = [1, 2, 3, 4],
			b = deepClone(a);
		a[0] = 2;
		console.log(a, b);
	</script>
</html>

image.png

#####1)改变a的值,b的值不受控制 #####2)说明深拷贝是会拷贝所有层级的属性