在JavaScript中,浅拷贝和深拷贝是两种复制对象的方式,它们的主要区别在于是否复制对象的引用类型属性
浅拷贝:浅拷贝只复制对象的基本类型的属性,如果属性是引用类型(如数组、对象),则复制的是引用,而不是实际的对象。这意味着如果你修改了复制后的对象的引用类型属性,原对象的对应属性也会被修改。
深拷贝:深拷贝不仅复制对象的基本类型的属性,还会复制引用类型的属性。这意味着它会创建一个新的对象,并复制原对象的所有属性和嵌套的属性。因此,修改复制后的对象的任何属性,都不会影响到原对象。
浅拷贝的实现
// 接收传进来的参数 可能是数组 或者是对象
function clone(obj) {
// 进行obj 参数类型的判断
// 如果 object ==> {} array ==>[]
const newObj = Array.isArray(obj) ? [] : {}
// 遍历老对象 或者 老数组
for (const key in obj) {
// 进行赋值操作
// key 属性名
newObj[key] = obj[key]
// 但是这里有一个问题, 比如说 引用数据类型 对象啊 数组啊, 你这样赋值的话,相当于
// 直接把地址拷贝过来了, 修改新对象里面的引用数据类型的属性的时候,也会影响到了源对象
// 类似
// newfruit[name] = fruit[name]
}
return newObj
}
深拷贝的实现
深拷贝的主要实现步骤相较于浅拷贝 主要在于 对于原对象
中引用数据类型的属性值
的处理
主要使用的是函数递归
的方法 一层一层的走下去
/**
* 深拷贝的思路:
* 1. 对进行被拷贝对象数据类型的判断 数组 || 对象
* 2. 如果是数组 就创建一个空数组 ; 如果是对象 就创建一个空对象 (主要为了开辟新的内存空间)
* 3. 遍历数组 或者 对象 (depend on 原对象的类型)
* 4. 原对象身上的基础数据类型直接赋值即可. 如果是引用数据类型,进行递归函数调用
* 5. 返回新创建的数组 或者 对象
*
*/
// 接收传进来的参数 可能是数组 或者是对象
function deepClone(obj) {
// 进行obj 参数类型的判断
// 如果 object ==> {} array ==>[]
const newObj = Array.isArray(obj) ? [] : {}
// 遍历老对象 或者 老数组
for (const key in obj) {
// 如果是引用数据类型的话
if (typeof newObj[key] == "object") {
newObj[key] = deepClone(obj[key])
}
// 基础数据类型 直接进行赋值操作
// key 属性名
newObj[key] = obj[key]
// 但是这里有一个问题, 比如说 引用数据类型 对象啊 数组啊, 你这样赋值的话,相当于
// 直接把地址拷贝过来了, 修改新对象里面的引用数据类型的属性的时候,也会影响到了源对象
// 类似
// newfruit[name] = fruit[name]
}
return newObj
}