当前位置:   article > 正文

深拷贝和浅拷贝的区别及实现方法_深拷贝浅拷贝的实现方式和区别

深拷贝浅拷贝的实现方式和区别

查阅多篇文章后,自己归纳总结对深拷贝和浅拷贝的理解,不足之处,还望多多指导

一、引言


基本数据类型 的数据赋值后,更改赋值后的变量,两者互不影响;

let a = 100;
let b = a;
a = 200;

console.log(a); // 200
console.log(b); // 100
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

引用数据类型 的数据赋值后,将存放在栈内存中的地址赋值给接收的变量,更改赋值后的变量,会影响到原来的数据

// 复杂数据类型:Array、Object
let obj1 = {
    name:"小李",
    age:18
	}

let obj2 = obj1
obj1.age = 25;

console.log( obj1 ); 	// {name:"小李", age:25}
console.log( obj2 ); 	// {name:"小李", age:25}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

针对以上问题 引出了本文的解决方案 深拷贝浅拷贝

二、浅拷贝


定义:
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。
如果属性是基本类型,拷贝的就是基本类型的值。
如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

缺陷: 浅拷贝只能实现一层的拷贝,无法进行深层次的拷贝

实现方法

1.Object.assign()

ES6中拷贝对象的方法,接受的第一个参数是拷贝的目标,剩下的参数是拷贝的源对象(可以是多个)

语法:Object.assign(target, ...sources)

举个栗子:

let obj1 = {
	name: "小李",
	age: 18
}
// Object.assign()  会返回一个新对象 

// 这种写法和下面写法实现效果一样
// let obj2 = Object.assign({}, obj1)

let obj2 = {}
Object.assign(obj2, obj1)
obj1.name = '小张';
obj1.age = '25';

console.log(obj1); // {name:"小张", age:25}
console.log(obj2); // {name:"小李", age:18}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

2.concat()

语法:concat() 合并两个或多个数组,返回一个新数组。原数组不变

举个栗子:

let arr = [1,2,3,4];
let newArr = arr.concat()
arr.push(5);

console.log(arr);		// [1,2,3,4,5]
console.log(newArr );	// [1,2,3,4]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.扩展运算符

如果对象中的属性都是基本数据类型的话,使用扩展运算符更加方便

举个栗子:

let obj1 = {
	name: "小李",
	age: 18
}
let obj2 = {...obj1}

obj1.name = '小张';
obj1.age = '25';
console.log(obj1, obj2);


let arr = [1, 2, 3]
let newArr = [...arr]
arr[0] = 999
console.log(arr, newArr)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

运行结果:
在这里插入图片描述

三、深拷贝


不管原数据中值是什么类型的数据,拷贝后的新数据跟原数据是相互独立,没有关联的

实现方法

1. 利用json数据和json字符串之间的转换

JSON.stringify() 将对象转换成JSON字符串

JSON.parse() 反序列化将JSON字符串变成一个新的对象

对于日常的开发需求(对象和数组),使用这种方法是最简单和快捷的

缺点: 无法实现对对象中 方法 的拷贝,会显示为undefined

let obj1 = {
	name: "小李",
	age: 18,
	father: {
		age: 40
	},
	fn: function () {
		return 123
	}
}
let temp = JSON.stringify(obj1)
let obj2 = JSON.parse(temp)

obj1.father.age = 50;

console.log(obj1); 		// {name:"小李", age:18, father:{age:50},fn()}
console.log(obj2); 		// {name:"小张", age:25, father:{age:40}}
console.log(obj2.fn) 	// underfind
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.$.extend()

直通车: https://www.jquery123.com/jQuery.extend/.

语法: jQuery.extend([deep], target, object1, [objectN])

deep默认为false

举个栗子:

// 注意要引入jQuery的CDN才能使用该方法
let obj1 = {
	name: "小李",
	age: 18,
	father: {
		age: 40
	},
	fn: function () {
		return 123
	}
}

let obj2 = $.extend(true, {}, obj1)

obj1.father.age = 50;

console.log(obj1,obj2);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

运行结果:
在这里插入图片描述

3. 递归

function deepClone(obj) {
	// 定义一个对象,用来确定当前的参数是数组还是对象
	let objClone = Array.isArray(obj) ? [] : {};
	// 判断obj是否存在,且类型是对象。(typeof [] 也是 object)
	if (obj && typeof obj === "object") {
		// 遍历参数的键
		for (key in obj) {
			// hasOwnProperty() 方法不会检测对象的原型链,只会检测当前对象本身存在该属性时才返回 true,常与for...in使用
			// 判断对象是否存在该属性
			if (obj.hasOwnProperty(key)) {
				// 值是对象就递归
				if (obj[key] && typeof obj[key] === "object") {
					objClone[key] = deepClone(obj[key]);
				} else {
					// 基本数据类型  直接赋值
					objClone[key] = obj[key];
				}
			}
		}
	}
	return objClone;
}
let a = {
	name: "小李",
	age: 18,
	father: {
		name: "大李",
	},
	fn: function () {
		return 123
	}
}
let b = deepClone(a)
a.father.name = "小李他爸"

console.log(a, b);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

运行结果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/68270
推荐阅读
相关标签
  

闽ICP备14008679号