【VUE】深入讨论关于VUE的深拷贝和浅拷贝问题
一、深拷贝和浅拷贝的定义:
1、深拷贝 :指拷贝对象的具体内容,并且为对象分配新的内存地址。深拷贝结束之后,两个对象虽然存的值是一样的,但是内存地址不一样,互不影响,互不干涉。
2、浅拷贝 :指对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。浅拷贝只会拷贝基本数据类型的值,以及实例对象的引用地址,并不会复制一份引用地址所指向的对象。
深拷贝和浅拷贝是两种复制对象的方式。浅拷贝只复制对象的顶层属性,如果对象的属性值是一个引用类型,那么复制的只是这个引用,而不是引用的对象。而深拷贝则会递归地复制对象的所有层级,包括引用的对象。
二、Vue中的数据响应式与深浅拷贝
Vue通过Object.defineProperty()实现数据的响应式更新。当我们对Vue实例的data属性中的对象进行操作时,Vue会监听这些变化,并更新DOM。但由于Vue只能监听到data属性对象的变化,而无法监听到深层对象的变化,因此在某些情况下,我们可能需要手动进行深拷贝。
三、深拷贝与浅拷贝的实现方法
浅拷贝可以通过扩展运算符...
或Object.assign()
实现,另外数组或对象的直接赋值也是浅拷贝的一种,而深拷贝通常需要递归地复制嵌套对象。
以下是一个使用JSON.parse(JSON.stringify())
实现深拷贝的例子:
// 原始对象
let originalObject = {
name: 'John',
age: 30,
address: {
city: 'New York',
street: '123 Main St'
}
};
// 使用JSON.parse(JSON.stringify())进行深拷贝
let deepCopy = JSON.parse(JSON.stringify(originalObject));
// 修改深拷贝对象的属性,不会影响原始对象
deepCopy.name = 'Jane';
deepCopy.address.city = 'Los Angeles';
console.log(originalObject); // { name: 'John', age: 30, address: { city: 'New York', street: '123 Main St' } }
console.log(deepCopy); // { name: 'Jane', age: 30, address: { city: 'Los Angeles', street: '123 Main St' } }
请注意,JSON.parse(JSON.stringify())
可能不适用于所有情况,例如当对象中包含函数、undefined、循环引用等时候。对于这些复杂的情况,可能需要自己编写一个深拷贝的函数来处理。
比如,可以使用for循环遍历每一个对象,进行属性赋值。例如:
// 假设我们有一个对象
const sourceObject = {
name: 'Alice',
age: 25,
city: 'New York'
};
// 创建一个空对象,用于存放深拷贝后的属性
const deepCopyObject = {};
// 使用Object.keys()获取源对象的所有属性名
const keys = Object.keys(sourceObject);
// 使用for循环遍历属性名
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
// 检查属性值是否为对象,如果是则递归深拷贝
if (typeof sourceObject[key] === 'object' && sourceObject[key] !== null) {
deepCopyObject[key] = JSON.parse(JSON.stringify(sourceObject[key]));
} else {
// 如果不是对象,则直接赋值
deepCopyObject[key] = sourceObject[key];
}
}
// 输出深拷贝后的对象
console.log(deepCopyObject);