JS 深拷贝与浅拷贝知识全攻略
2023-09-05 08:08:32
目录
- 什么是深拷贝和浅拷贝?
- 深拷贝与浅拷贝的区别
- 浅拷贝的实现方式
- 深拷贝的实现方式
- 手动深拷贝
- JSON 深拷贝
- Lodash 深拷贝
- 何时使用深拷贝,何时使用浅拷贝
- 总结
正文
1. 什么是深拷贝和浅拷贝?
在JavaScript中,变量可以存储两种类型的数据:基本类型和引用类型。基本类型包括数字、字符串和布尔值,而引用类型包括对象和数组。
- 浅拷贝 :浅拷贝只复制一层对象的属性,即只复制对象的直接属性,而不复制对象的嵌套属性。
- 深拷贝 :深拷贝会复制对象的所有属性,包括对象的嵌套属性。
2. 深拷贝与浅拷贝的区别
下表列出了深拷贝与浅拷贝的区别:
特征 | 浅拷贝 | 深拷贝 |
---|---|---|
复制层次 | 只复制一层属性 | 复制所有属性 |
复制方式 | 按引用复制 | 按值复制 |
结果 | 两个对象指向同一块内存地址 | 两个对象指向不同的内存地址 |
3. 浅拷贝的实现方式
浅拷贝可以通过使用对象的赋值运算符(=)来实现。例如:
const obj1 = {
name: 'John Doe',
age: 30
};
const obj2 = obj1;
在上面的代码中,obj2被赋值为obj1的引用。这意味着obj2和obj1指向同一块内存地址。因此,对obj2的任何更改都会反映在obj1上,反之亦然。
4. 深拷贝的实现方式
深拷贝可以通过多种方式来实现,包括手动深拷贝、JSON 深拷贝和 Lodash 深拷贝。
4.1 手动深拷贝
手动深拷贝可以通过递归的方式来实现。递归是一种函数调用自身的编程技术。在手动深拷贝中,我们可以使用递归来复制对象的所有属性,包括对象的嵌套属性。
例如,我们可以使用以下代码来实现手动深拷贝:
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
const newObj = Array.isArray(obj) ? [] : {};
for (const key in obj) {
newObj[key] = deepCopy(obj[key]);
}
return newObj;
}
在上面的代码中,deepCopy()函数首先检查obj是否是一个对象或数组。如果不是,则直接返回obj。
如果是对象或数组,则创建一个新的对象或数组newObj。然后,使用for...in循环遍历obj的所有属性。对于每个属性,使用deepCopy()函数递归复制该属性的值。
最后,返回newObj。
4.2 JSON 深拷贝
JSON 深拷贝可以通过使用JSON.parse()和JSON.stringify()方法来实现。JSON.parse()方法可以将JSON字符串解析为JavaScript对象,而JSON.stringify()方法可以将JavaScript对象转换为JSON字符串。
例如,我们可以使用以下代码来实现JSON 深拷贝:
const obj1 = {
name: 'John Doe',
age: 30
};
const obj2 = JSON.parse(JSON.stringify(obj1));
在上面的代码中,首先使用JSON.stringify()方法将obj1转换为JSON字符串。然后,使用JSON.parse()方法将JSON字符串解析为JavaScript对象obj2。
这样,obj2就成为了obj1的深拷贝。
4.3 Lodash 深拷贝
Lodash是一个流行的JavaScript库,提供了许多有用的函数,其中包括一个深拷贝函数。我们可以使用以下代码来实现Lodash 深拷贝:
const obj1 = {
name: 'John Doe',
age: 30
};
const obj2 = _.cloneDeep(obj1);
在上面的代码中,我们使用_.cloneDeep()函数来复制obj1。这样,obj2就成为了obj1的深拷贝。
5. 何时使用深拷贝,何时使用浅拷贝
浅拷贝和深拷贝都有其各自的用途。一般来说,当我们只需要复制对象的直接属性时,就可以使用浅拷贝。而当我们需要复制对象的嵌套属性时,就需要使用深拷贝。
例如,如果我们有一个对象,其中包含一个数组属性,并且该数组属性包含另一个对象,那么我们需要使用深拷贝来复制该对象,才能确保复制出该对象的所有属性,包括数组属性和数组属性中的对象。
6. 总结
深拷贝与浅拷贝是JavaScript中两种重要的复制技术。深拷贝可以复制对象的所有属性,包括对象的嵌套属性,而浅拷贝只复制一层对象的属性。
在实际应用中,我们可以根据需要选择使用深拷贝或浅拷贝。一般来说,当我们只需要复制对象的直接属性时,就可以使用浅拷贝。而当我们需要复制对象的嵌套属性时,就需要使用深拷贝。