前端基础知识库-JavaScript对象的深拷贝

简介: 在JavaScript数据类型分为基础类型和引用类型,而引用类型又称为对象,可见了解对象是我们真正掌握JavaScript语言的必备技能。本章主要与大家一起去探索JavaScript对象的一些经常被我们忽略的以及难以理解的知识。好了,废话不多说让我们一起进入JavaScript对象的世界吧。

前言


-路漫漫其修远兮,我将上下而求索。

在JavaScript数据类型分为基础类型和引用类型,而引用类型又称为对象,可见了解对象是我们真正掌握JavaScript语言的必备技能。本章主要与大家一起去探索JavaScript对象的一些经常被我们忽略的以及难以理解的知识。好了,废话不多说让我们一起进入JavaScript对象的世界吧。

基本概念


  • 个人理解:深浅拷贝在JavaScript中只是对于引用类型来说的,因为在JavaScript中基本数据类型是通过值传递的,所以他们不存在深拷贝一说。
  • 对象的浅拷贝:即只复制对象在栈内存中的保存的地址值,例如我们直接用赋值符号拷贝另一个对象的值。
  • 对象的深拷贝:复制对象存在堆内存中的实际值并且重新在栈内存中生成一份指向新堆内存中的地址值。
  • 原因:JavaScript中的引用类型的数据是被存放在堆内存中的,他们在栈内存中的变量只是保存了一个指向对堆内存中值的指针(类似与c中的指针),因此我们在访问引用类型的数据时只能先从栈中取出对象的指针地址,然后才会从堆内存中取得对象的数据。这也是JavaScript对象用赋值符号只能复制指针地址的原因。

为何进行对象深拷贝


  • 如果只是对对象数据类型进行简单的浅拷贝,则新复制的值和老值会共用堆内存中的数据,导致值不确定性,例如:
let a={
    val:"test"
}
console.log(a.val)//"test"
let b=a
b.val="test2"
console.log(a.val)//"test2"
console.log(b.val)//"test2"

这也是导致前端显示异常的根本原因之一

  • 提高代码可维护性,多人合作开发时,共用某份是对象类型的数据如果只进行简单的浅拷贝则很影响他人。

深拷贝的方法

  • JSON.stringfy() => JSON.parse() 即将一个对象先解析为json 字符串然后再解析
let a={
    val:'test'
}
let b=JSON.parse(JSON.stringfy(a))

优点:操作简单。

缺点:1.如果对象很大会占用内存 2.对于复杂的对象类型(即属性是诸如 Map, Set, RegExp, Date, ArrayBuffer,function和其他内置类型),在进行序列化时会丢失。 丢失属性。3.无法进行对象的循环处理。

  • 使用object.assign()来实现:
let originobj= {
  'name': 'test',
  'weight': 50
};
let newobj = Object.assign({}, originobj, {
  'test': '111'
});
newobj.age = 60;
console.log('originobj', originobj); //{name: "test", weight: 50}
console.log('newobj', newobj); //{name: "test", weight: 50, test: "111", age: 60}

优点:方便快捷 不会丢失原数据 缺点:只能复制简单的对象(),即Object.assign()拷贝的只是属性值 注意:如果对象中的属性还是对象则Object.assign()不会进行值拷贝,只能进行引用拷贝

  • 为了解决JSON和assign复制带来的问题,我们可以采用循环递归复制,即在遍历赋值对象属性的时候,遇到属性是引用类型的,则把这个属性展开赋值,如下代码所示:
function cloneDeep(newobj={},originObj){
    for(let key in originObj){
        //判断是否是对象类型
        if(originObj[key] && originObj[key] instanceof object){
            //递归将对象类型赋值给新数组
            newobj[key] = cloneDeep(originObj[key])
        }else{
            newobj[key] = originObj[key]
        }
    }
    return newobj
}
let obj = {a:{b:'test'},c:"test2"}
//此时完全copy了obj的值
let obj1 = cloneDeep(obj)//{a:{b:'test'},c:"test2"}

总结


在编程的世界中熟悉某一门语言的基本要求就是掌握这门语言定义的数据类型,不同的语言中所定义的数据类型往往不同。这也是我们同时掌握多中编程语言的难点。但幸运的是他们底层设计原理都是相互借鉴的,这也成为了我们能够掌握夺门语言的关键点之一。


相关文章
|
22天前
|
前端开发 机器人 API
前端大模型入门(一):用 js+langchain 构建基于 LLM 的应用
本文介绍了大语言模型(LLM)的HTTP API流式调用机制及其在前端的实现方法。通过流式调用,服务器可以逐步发送生成的文本内容,前端则实时处理并展示这些数据块,从而提升用户体验和实时性。文章详细讲解了如何使用`fetch`发起流式请求、处理响应流数据、逐步更新界面、处理中断和错误,以及优化用户交互。流式调用特别适用于聊天机器人、搜索建议等应用场景,能够显著减少用户的等待时间,增强交互性。
143 2
|
21天前
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
34 0
|
22天前
|
JavaScript 前端开发 API
Vue.js:现代前端开发的强大框架
【10月更文挑战第11天】Vue.js:现代前端开发的强大框架
62 41
|
4天前
|
设计模式 前端开发 JavaScript
揭秘!前端大牛们如何巧妙利用JavaScript,打造智能交互体验!
【10月更文挑战第30天】前端开发领域充满了无限可能与创意,JavaScript作为核心语言,凭借强大的功能和灵活性,成为打造智能交互体验的重要工具。本文介绍前端大牛如何利用JavaScript实现平滑滚动、复杂动画、实时数据更新和智能表单验证等效果,展示了JavaScript的多样性和强大能力。
15 4
|
2天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
6天前
|
JavaScript 前端开发 开发者
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第27天】在前端开发领域,Vue.js和Angular是两个备受瞩目的框架。本文对比了两者的优劣,Vue.js以轻量级和易上手著称,适合快速开发小型到中型项目;Angular则由Google支持,功能全面,适合大型企业级应用。选择时需考虑项目需求、团队熟悉度和长期维护等因素。
14 1
|
14天前
|
JSON 前端开发 数据格式
前端的全栈之路Meteor篇(五):自定义对象序列化的EJSON介绍 - 跨设备的对象传输
EJSON是Meteor框架中扩展了标准JSON的库,支持更多数据类型如`Date`、`Binary`等。它提供了序列化和反序列化功能,使客户端和服务器之间的复杂数据传输更加便捷高效。EJSON还支持自定义对象的定义和传输,通过`EJSON.addType`注册自定义类型,确保数据在两端无缝传递。
|
17天前
|
前端开发 JavaScript 安全
JavaScript前端开发技术
JavaScript(简称JS)是一种广泛使用的脚本语言,特别在前端开发领域,它几乎成为了网页开发的标配。从简单的表单验证到复杂的单页应用(SPA),JavaScript都扮演着不可或缺的角色。
17 3
|
7天前
|
JavaScript 前端开发 API
前端框架对比:Vue.js与Angular的优劣分析与选择建议
【10月更文挑战第26天】前端技术的飞速发展让开发者在构建用户界面时有了更多选择。本文对比了Vue.js和Angular两大框架,介绍了它们的特点和优劣,并给出了在实际项目中如何选择的建议。Vue.js轻量级、易上手,适合小型项目;Angular结构化、功能强大,适合大型项目。
11 0
|
10天前
|
前端开发 JavaScript UED
"前端小技巧大揭秘:JS如何将后台时间戳秒变亲切小时前、分钟前,让用户秒懂,提升互动体验!"
【10月更文挑战第23天】在Web开发中,将后台返回的时间戳转换为“小时前”、“分钟前”、“刚刚”等友好的时间描述是常见需求。本文介绍如何用JavaScript实现这一功能,通过计算当前时间和时间戳的差值,返回相应的描述,提升用户体验。
18 0