浅拷贝和深拷贝

简介: 在 JavaScript 中,拷贝一个对象是一项常见的操作,常用的拷贝方式包括浅拷贝和深拷贝。

28. 浅拷贝和深拷贝

在 JavaScript 中,拷贝一个对象是一项常见的操作,常用的拷贝方式包括浅拷贝和深拷贝。

1. 浅拷贝

浅拷贝(shallow copy)是指只复制对象的第一层属性,而不会递归地复制其子对象(即其引用类型属性),新的对象与原始对象共享同一个子对象。如果修改了子对象,则新对象和原始对象都会受到影响。浅拷贝有以下几种方式:

1. 展开运算符 (...)

扩展运算符可以用于展开数组或对象,也可以用于浅拷贝对象。

const obj = {
    
  name: "Jack",
  age: 18,
  friends: ["Jarry", "Peter"]
}
const objCopy = {
    ...obj }
console.log(objCopy);
objCopy.friends.push("Jace")
console.log(obj.friends);//['Jarry', 'Peter', 'Jace']
2. Object.assign(target, ...sources)

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象中。它会返回目标对象。

const obj = {
    
  name: "Jack",
  age: 18,
  friends: ["Jarry", "Peter"]
}
const objCopy = Object.assign({
   }, obj)
console.log(objCopy);
objCopy.friends.push("Jace")
console.log(obj.friends);//['Jarry', 'Peter', 'Jace']
3. Array.prototype.slice()

slice() 方法返回一个新的数组对象,这个对象是一个浅拷贝数组的一部分到一个新的数组对象,原始数组不会被改变。

const arr = [1, 2, 3, [4, 5]]
const arrCopy = arr.slice()
console.log(arrCopy);//[1, 2, 3, Array(2)]
arrCopy[3].push(6)
console.log(arr);//[1, 2, 3, Array(3)]

2. 深拷贝

深拷贝(deep copy)是指完全复制一个对象,包括其所有子对象,新的对象与原始对象互不干扰,修改一个对象的属性不会影响另一个对象。深拷贝有以下几种方式:

1. JSON.parse(JSON.stringify(object))

使用 JSON.stringify() 方法将对象转为 JSON 字符串,然后使用 JSON.parse() 方法将 JSON 字符串转回对象,这样可以实现深拷贝。不过需要注意的是,这种方式有一些限制,例如无法处理函数、undefined 等数据类型。

const obj = {
    
  name: "Jack",
  age: 18,
  friends: ["Jarry", "Peter"],
  un: undefined,
  fn: function(){
   }
}
const objCopy = JSON.parse(JSON.stringify(obj))
console.log(objCopy);//{name: 'Jack', age: 18, friends: Array(2)}
objCopy.friends.push("Bob")
console.log(obj.friends);//['Jarry', 'Peter']
console.log(objCopy.friends);//['Jarry', 'Peter', 'Bob']

2. 递归拷贝

递归拷贝是指在拷贝对象时,对对象的每个属性递归地进行拷贝。可以使用 for...in 循环遍历对象的属性,并对每个属性进行递归拷贝。

const obj = {
    
  name: "Jack",
  age: 18,
  friends: ["Jarry", "Peter"],
  set: set,
  un: undefined,
  fn: function(){
   }
}
function deepCopy(obj) {
   
  if(typeof obj !== "object" || obj === null) return obj;
  const newObj = Array.isArray(obj) ? [] : {
   };
  for(const key in obj) {
   
    newObj[key] = deepCopy(obj[key])
  }
  return newObj
}
const objCopy = deepCopy(obj)
console.log(objCopy);//{name: 'Jack', age: 18, friends: Array(2), un: undefined, fn: ƒ}

在使用递归拷贝时,也需要注意避免循环引用的情况。

  • 循环引用问题:
// 循环引用
function deepCopy(obj) {
   
  if(typeof obj !== "object" || obj === null) return obj;
  const newObj = Array.isArray(obj) ? [] : {
   };
  for(const key in obj) {
   
    newObj[key] = deepCopy(obj[key])
  }
  return newObj
}
obj.info = obj;//循环引用
const objCopy = deepCopy(obj)//报错  Uncaught RangeError: Maximum call stack size exceeded
相关文章
|
5天前
局部变量和成员变量
局部变量和成员变量 1.定义的位置不一样【重点】 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中 2.作用范围不一样【重点】 局部变量:只有方法当中才可以使用,出了方法就不能再用 成员变量:整个类全都可以通用。 3.默认值不一样【重点】 局部变量:没有默认值,如果要想使用,必须手动进行赋值 成员变量:如果没有赋值,会有默认值,规则和数组一样局部变量和成员变量 1.定义的位置不一样【重点】 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中 2.作用范围不一样【重点】 局部变量:只有方法当中才可以使用,出了方法就不能再用 成员变量:整个类全都可以通用。 3.默认值不一
12 3
|
3月前
局部变量和成员变量
1.定义的位置不一样【重点】局部变量:在方法的内部 局部变量和成员变量 1.定义的位置不一样【重点】 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中 2.作用范围不一样【重点】 局部变量:只有方法当中才可以使用,出了方法就不能再用 成员变量:整个类全都可以通用。 3.默认值不一样【重点】 局部变量:没有默认值,如果要想使用,必须手动进行赋值 1.定义的位置不一样【重点】 局部变量:在方法的内部
18 0
|
3天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
29天前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19262 29
|
30天前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18803 20
|
29天前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17508 13
Apache Paimon V0.9最新进展
|
1月前
|
存储 人工智能 前端开发
AI 网关零代码解决 AI 幻觉问题
本文主要介绍了 AI Agent 的背景,概念,探讨了 AI Agent 网关插件的使用方法,效果以及实现原理。
18694 15
|
29天前
|
人工智能 自然语言处理 搜索推荐
评测:AI客服接入钉钉与微信的对比分析
【8月更文第22天】随着人工智能技术的发展,越来越多的企业开始尝试将AI客服集成到自己的业务流程中。本文将基于《10分钟构建AI客服并应用到网站、钉钉或微信中》的解决方案,详细评测AI客服在钉钉和微信中的接入流程及实际应用效果,并结合个人体验分享一些心得。
9910 9
|
1月前
|
消息中间件 弹性计算 关系型数据库
函数计算驱动多媒体文件处理解决方案体验评测
从整体解读到部署体验,多方位带你了解如何利用函数计算驱动多媒体文件处理,告别资源瓶颈。
10441 13
|
23天前
|
存储 JSON Serverless
西游再现,函数计算一键部署 Flux 超写实文生图模型部署
参与体验活动生成西游人物图像,既有机会赢取好礼!本次实验在函数计算中内置了flux.1-dev-fp8大模型,通过函数计算+Serverless应用中心一键部署Flux模型,快速生成超写实图像。首次开通用户可领取免费试用额度,部署过程简单高效。完成部署后,您可以通过修改提示词生成各种风格的图像,体验Flux模型的强大绘图能力。
西游再现,函数计算一键部署 Flux 超写实文生图模型部署