"浅拷贝与深拷贝:你真的懂吗?"

  在编程中,我们经常需要对对象进行复制或拷贝操作。针对引用类型的拷贝,可以分为浅拷贝和深拷贝两种方式。本文将介绍这两种拷贝方式,并探讨它们的使用场景及方法。

浅拷贝

  浅拷贝是指通过某个方法将一个对象完整地复制一份后,原对象的修改会影响到新的对象。下面是几种常见的浅拷贝方法:

Object.create(obj)

Object.create(obj) 方法会创建一个以 obj 为原型的新对象,新对象将继承 obj 对象的属性和方法。这种方式创建的对象被称为原型继承对象。

  你看图片,Object会隐式继承obj对象的东西,它是一个空数组,将obj.name改成小红,但是object.name随着改变 图片如下

Object.assign({},a)

  Object.assign() 方法用于将一个或多个源对象的属性复制到目标对象中,并返回目标对象。当我们将空对象作为目标对象传递给 Object.assign() 时,实际上是创建了源对象的一个浅拷贝。

  当我改变source.a的值的时候,对象target中的a没发改变但是还有原因的

来在展示一个   你看是不是source.b.name值小明改成小红,target中的也发生改变呢?这个就要说,编译器时,存储引用型数数据要存放在堆里面,而target浅拷贝source的存储地址,当source.b.name中的值发生改变,所以target也会改变,这个是重点。

总结来说,Object.assign({}, source) 方法可以用于创建源对象的浅拷贝。对于嵌套对象或数组,它只会进行浅层复制,因此对于深层嵌套的对象,需要使用其他方法来实现深拷贝。

\[\].concat(arr)

  [].concat(arr) 方法可以用于将一个或多个数组合并成一个新数组,并返回这个新数组。当我们将一个数组作为参数传递给 [].concat() 方法时,实际上是创建了这个数组的一个浅拷贝。

ini 复制代码
const arr2 = [1, 2, b={name:'小明'}];
const newArr = [].concat(arr2);
arr2[2].name='小红';
console.log(newArr);

  [].concat(arr) 方法可以用于将一个或多个数组合并成一个新数组,并返回这个新数组。对于包含对象或其他引用类型数据的数组,需要注意浅拷贝可能会带来的影响。如果需要进行深拷贝,可以使用其他方法来实现。

解构

  解构赋值在数组和对象的解构过程中,可以实现浅拷贝的效果。当我们使用解构赋值从一个数组或对象中提取值并赋给新的变量时,新变量将引用原始数组或对象中对应位置的值。

ini 复制代码
const arr = [1, 2, b={name:'小明'}]; 
const newArr = [...arr];
arr[2].name='小红'
console.log(newArr)

  解构赋值只能实现浅拷贝。如果原数组或对象中的元素是对象或其他引用类型,那么新数组或对象中的对应元素仍然会和原数组或对象中的元素指向同一个内存地址。这意味着,在修改新数组或对象中的元素时,可能会影响到原数组或对象中的对应元素。

arr.toReversed().reverse()

这个方法是数组反转之后,在反转得到了原先的数组,接下来下面展示

ini 复制代码
const arr = [1, 2, b={name:'小明'}]; 
const newArr = arr.toReversed().reverse()
arr[2].name='小红'
console.log(newArr)

这个就arr.toReversed().reverse(),浅拷贝的方法

深拷贝

  深拷贝是指创建一个完全独立的对象副本,原对象的修改不会影响到新的对象。下面介绍一种常用的深拷贝方法:

  JSON.parse(JSON.stringify(obj))可以将一个对象转换为字符串再转换回对象,从而实现深拷贝。这种方法会创建一个新对象,并复制所有属性和值,包括嵌套的引用类型。然而,需要注意的是,这种方法有两个缺陷: 输出

  1. 无法处理undefined、function、Symbol等特殊数据类型,这些数据类型在转换过程中会被忽略。
  2. 无法处理循环引用,即对象中存在相互引用的情况。在处理循环引用时,会导致栈溢出错误。

  因此,在使用JSON.parse(JSON.stringify(obj))进行深拷贝时,需要注意这两个缺陷,并根据实际情况选择其他方法或进行额外的处理。

  综上所述,浅拷贝和深拷贝是针对引用类型的拷贝方式。浅拷贝会复制对象或数组的第一层内容,而深拷贝则会创建一个完全独立的对象副本。根据需求选择适当的拷贝方式可以确保程序的正确运行和数据的安全性。   下期我来教大家手动写适配器 喜欢的来个关注 点赞 这个也是以后写文章的动力所在 谢谢大家能观看我的文章 咱下期在见 拜拜

相关推荐
总要学点什么6 小时前
第105篇:三维特效-流动图片墙体效果——让箭头沿墙长滚,它俩竟是同一份代码
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
Agent世界7 小时前
用 CDP 做发布自动化:四道机器闸门与产物验收
前端·javascript
FungLeo7 小时前
成为全栈·Vue 管理后台篇·编辑器图片上传:从文件选择到文章附件关联
前端·vue.js·编辑器·markdown·文件上传·formdata·附件管理
总要学点什么7 小时前
第104篇:三维特效-流动墙体效果——让贴图沿墙流动,它却只肯走一条对角线
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
某哈压力大8 小时前
SSH 突然 Connection reset?不是密钥坏了,是 OpenSSL 把 sshd 干趴了
前端·node.js·命令行
程序员大阳8 小时前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半8 小时前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳8 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
deli0078 小时前
写满 200GB 后 SSD 为什么掉到 95MB/s?SLC 缓存模型实测
前端
nice_lcj5209 小时前
LRU 缓存入门:它是什么、怎么用、面试怎么手写
java·数据结构·缓存·面试·lru