当前位置:首页 > 前端 > Vue > 正文内容

【VUE】深入讨论关于VUE的深拷贝和浅拷贝问题

virtualman9个月前 (03-22)Vue2143

一、深拷贝和浅拷贝的定义:

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);

 

相关文章

聊聊vue3中ref和reactive的区别与底层实现

聊聊vue3中ref和reactive的区别与底层实现

  Vue 3 中引入了新的响应式 API,包括 ref 和 reactive,这两个API都用于创建响应式引用,但是它们之间存在一些关键的区别,以及它们在底层的实现机制也有所不同。 一、ref 和 reactive 的区别 0. 一句话区分 re...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。