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

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

浅拷贝

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

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. 无法处理undefinedfunctionSymbol等特殊数据类型,这些数据类型在转换过程中会被忽略。
  2. 无法处理循环引用,即对象中存在相互引用的情况。在处理循环引用时,会导致栈溢出错误。

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

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

相关推荐
phltxy5 分钟前
解锁JavaScript WebAPI:从基础到实战,打造交互式网页
开发语言·javascript
前端小趴菜0519 分钟前
TypeScript
前端·typescript
getapi1 小时前
在宝塔面板中部署 Vue 项目打包后的 dist 文件作为前端
前端·javascript·vue.js
5967851541 小时前
css浮动
前端·css·html
我想发发发2 小时前
已经安装了ROS环境却还是报错`ModuleNotFoundError: No module named ‘rclpy‘`
前端·人工智能·chrome·机器人
—Qeyser2 小时前
Flutter 组件通信完全指南
前端·javascript·flutter
天天进步20152 小时前
从脚本到服务:5 分钟通过 Botasaurus 将你的爬虫逻辑转化为 Web API
前端·爬虫
沛沛老爹2 小时前
Web转AI架构篇:Agent Skills vs MCP-混合架构设计模式实战指南
java·前端·人工智能·架构·llm·rag
张张努力变强2 小时前
C++类和对象(一):inline函数、nullptr、类的定义深度解析
开发语言·前端·jvm·数据结构·c++·算法
且去填词2 小时前
深入理解 GMP 模型:Go 高并发的基石
开发语言·后端·学习·算法·面试·golang·go