【JavaScript基础】 赋值,浅拷贝,深拷贝
一般深浅拷贝只针对复杂数组和对象,即引用类型,理解什么是深浅拷贝,为什么要用深浅拷贝 比记住方法更重要。这样才能在工作中知道何时应该用深浅拷贝,方法百度到处是。
- 什么是赋值,什么是深拷贝,什么是浅拷贝
1.赋值: 强行赋值,将两个对象的指向同一块内存地址,两个对象将发生联动。(基本数据类型不在此考虑,基本数据不会发生,此处只考虑引用类型。)
2.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用
3.深拷贝: 创建一个新的对象和数组,将原对象的各项属性的“值”(数组的所有元素)拷贝过来,是“值”而不是“引用”
理解:
1.直接赋值其实只复制了原对象的指针,引用对象和原对象指向同一个内存地址(内存共享,只是对象的名称不同而已)。这不能算真正的拷贝,因为修改引用对象时,内存地址发生改变,居然会影响原对象!!!
2.浅拷贝是创建一个完全和原对象一模一样的数组(第一层级/深度),中心思想是创建一个新对象(开辟一个新的内存地址),将原对象的属性逐个(遍历)拷贝到新的对象中。
3.深拷贝则是创建一个完全和原对象一模一样的数组(所有层级/深度),中心思想是创建一个新对象(开辟一个新的内存地址)用递归逐层复制对象。如果原对象过于复杂,使用深拷贝必然会造成不必要的性能损耗,则需要考虑是否真的使用深拷贝。
↑引用值的赋值过程
- 为什么要使用深、浅拷贝?如何证明拷贝成功了
1.我们不希望拷贝生成的新数组,会改变原数组。当我们改变新数组时,原数组不会随之发生改变,即证明拷贝成功了。
- 何时使用深拷贝,如何使用浅拷贝
1.深拷贝会导致性能的损耗。如果仅需拷贝原对象、数组的第一层级(深度),就用浅拷贝。如果需要完整拷贝,则需要使用深拷贝。
-
浅拷贝
请注意浅拷贝只能适用于,对象或者数组第一层级下为基本数据类型(数字,字符串),若数据结构第一层级下的结构不是基本数据类型,则会拷贝失败。(因为浅拷贝的代码就是只拷贝了原对象或者数组的第一层属性),如果这里用直接赋值强行指向同一内存地址,所有属性都被改变了。

let originObj = { name:"paul", age:19, address:['china'], hobbies:['sing','dance','ball'], family:{ dad:"tom", mother:"jerry" } }; let copyObj = copy(originObj); copyObj.name = "jim" //第一层级为基本数据类型,修改第一层级的数据不会发生改变 copyObj.age = 99; //第一层级为基本数据类型,修改第一层级的数据不会发生改变 copyObj.address[0]= "usa" // 第一层级下不是基本数据类型 copyObj.hobbies[0]="play games" // 第一层级下不是基本数据类型,修改数据会发生改变,说明拷贝已经失败 copyObj.family.mother = "helen" // 第一层级下不是基本数据类型,修改数据会发生改变,说明拷贝已经失败 function copy(obj){ let newObj = {} for(prop in obj){ if (obj.hasOwnProperty(prop)) { newObj[prop]= obj[prop] } } return newObj; };
实现浅拷贝的方法
对象方法:Object.assign({},obj)
数组方法:Array.contact() , Array.slice()
ES6扩展运算符:[...arr1] , {...obj1}
-
深拷贝

// 原生js代码实现深拷贝 let originObj = { name:"paul", age:19, address:['china'], hobbies:['sing','dance','ball'], family:{ dad:"tom", mother:"jerry" } }; function deepCopy(obj){ // 如果不是对象或者数组,说明是简单数据类型,直接引用即可 if (typeof obj !== 'object' || obj == null) { return obj }; let result; // 简单判断数据的类型 if(obj instanceof Array){ result = [] }else{ result = {} }; for (let key in obj){ if (obj.hasOwnProperty(key)) { console.log(key); // 递归深拷贝(只有递归才能逐级拷贝到深层的属性) result[key] = deepCopy(obj[key]) // result[key] = obj[key] 未递归只能算浅拷贝 } } return result }; let copyObj = deepCopy(originObj) copyObj.name = "jim" //所有层级均不会改变,深拷贝成功 copyObj.age = 99; //所有层级均不会改变,深拷贝成功 copyObj.address[0]= "usa" // 所有层级均不会改变,深拷贝成功 copyObj.hobbies[0]="play games" // 所有层级均不会改变,深拷贝成功 copyObj.family.mother = "helen" // 所有层级均不会改变,深拷贝成功 console.log(originObj); console.log(copyObj);
实现深拷贝的方法
一、通用方法,JSON.stringify()将对象转化为JSON字符串,再用JSON.parse() 把JSON字符串转化对象 JSON.parse(JSON.stringify(targetObj))
-缺点:受限于JSON类型格式,JSON并没有null, NaN, infinity,函数,正则、日期、函数都会出问题 (原理是因为受限于JSON类型格式,需补充JSON 的知识点)
二、lodash的cloneDeep方法,注意按需引入 import cloneDeep from 'lodash/cloneDeep'
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现