深度解析javascript中的浅复制和深复制

简介: 原文:深度解析javascript中的浅复制和深复制       在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型。我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型。
原文: 深度解析javascript中的浅复制和深复制

       在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型。我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型。而Object又包含Function,Array和Object自身。前面的五种类型叫做基本类型,而Object是引用类型。可能有人就要问,为什么要分基本类型和引用类型呢?后面你就会明白的。

     我们首先来看看浅复制和深复制的简洁定义:

  • 深复制:直接将数据复制给对应的变量
  • 浅复制:将数据的地址复制给对应的变量

而数据类型和我们要讨论的复制类型又有怎样的联系呢?我们试着摸索一下吧

实验一:

1 var a = "dengkunming";
2 var a1 = a;
3 alert(a1);//dengkunming
4 a="abc";
5 alert(a1);//dengkunming;

这段代码中我们把a赋值给a1,当a的值改变时,a1没有发生变化。

实验二:

1 var a = [0,1,2,3];
2 var a1= a;
3 alert(a1);//[0,1,2,3]
4 a[1]="变";
5 alert(a1);//[0,"变",2,3]

在这段代码中我们同样把a赋值给a1,当a的值改变的时候,a1却发生了变化。

     这是咋回事了,同样的操作其结果怎么会有差异了?我们回头看看,聪明的一休认为可能是这两个a有些不同。那些不同了?前面的是字符串,后面的数组。好像就是我们前面提到的基本类型和数据类型吧。那我们把数据类型换一下看看会有什么结果。

实验三:

1 var a = 3578;
2 var a1 = a;
3 alert(a1);//3578
4 a=8735;
5 alert(a1);//3578

实验四:

1 1 var a = {w1:2,w2:3}
2 2 var a1= a;
3 3 alert(a1);//{w1:2,w2:3}
4 4 a1.w1="邓";
5 5 alert(a);//{w1:"邓",w2:3}

    在这两组实验中,我们把数据类型分别换成了Number型和Object类型。实验三中可以发现a1不随a值的变化而变化,实验四中a会随着a1的变化而变化(这里和实验二略有不同,改变的是a1,当然你改变a的话,a1也会跟着变化)

   似乎我们可以得出个一般性的结论了:

    js中基本类型的赋值为深复制,而引用类型的赋值为浅复制。

   现在有必要把深复制和浅复制的定义扩展一下了。

  • 浅复制:就是把数据的地址赋值给对应变量,而没有把具体的数据复制给变量,变量会随数据值的变化而变化。
  • 深复制:就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。

实验五:

1 var a = {w1:2,w2:3}
2 var a1= a;
3 alert(a1);//{w1:2,w2:3}
4 var a={x1:7,x2:8}
5 alert(a1);//{w1:2,w2:3}

     按照我们上面的理论来讲,这里是浅复制。a1应该随着a的变化而变化呀,可在这里为什么会事与愿违了?这就是引用类型惹的祸了。对象赋值其实都是引用传值,传递的是一个地址。那么实验五中的第四行其实就是把变量a指向了一个新的地址。而a1还是指向的原来那个地址,原来地址中的值没变,所以a1就不会变。所以请记住:浅复制不会随着存储数据地址的变化而变化,只会随着数据值的变化而变化。

     那我们如何实现引用类型的深度复制呢?这就是老话题深度克隆了。就是需要自己写一个非原生的clone函数喽。

 1 function clone(obj){
 2     var o=[]; 
 3     if(obj.constructor== Array) {
 4         o=obj.slice(0);
 5        }else{
 6            o={};
 7            for(var i in obj){
 8                 o[i] = typeof obj[i] === "object" ? obj[i].clone() : obj[i];} 
 9        }
10        return o;
11 
12 }

    小可不才,文章中定会有所纰漏,望指出。也学一下大牛的语气,此文原创,转载请注明出处。如果你觉得文章还不错,就怒顶并推荐一下下吧!!!!

目录
相关文章
|
7天前
|
JavaScript 前端开发 IDE
TypeScript vs. JavaScript:技术对比与核心差异解析
TypeScript 作为 JavaScript 的超集,通过静态类型系统、编译时错误检测和强大的工具链支持,显著提升代码质量与可维护性,尤其适用于中大型项目和团队协作。相较之下,JavaScript 更灵活,适合快速原型开发。本文从类型系统、错误检测、工具支持等多维度对比两者差异,并提供技术选型建议,助力开发者合理选择。
92 1
|
22天前
|
存储 JavaScript 前端开发
JavaScript 语法全面解析
JavaScript 语法体系丰富且不断更新,从基础的变量声明、数据类型,到复杂的函数、对象、异步语法,每个知识点都需要开发者深入理解并灵活运用。本文梳理的 JS 语法核心内容,可为开发者提供系统的学习框架,后续还需通过大量实践(如编写交互组件、实现业务逻辑)巩固知识,逐步提升 JS 编程能力,应对前端开发中的各类挑战。
|
3月前
|
机器学习/深度学习 JavaScript 前端开发
JS进阶教程:递归函数原理与篇例解析
通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
142 19
|
4月前
|
JSON 前端开发 Serverless
Mock.js 语法结构全解析
Mock.js 的语法规范介绍,从数据模板定义规范和数据占位符定义规范俩部分介绍, 让你更好的使用 Mock.js 来模拟数据并提高开发效率。
|
6月前
|
数据采集 前端开发 JavaScript
金融数据分析:解析JavaScript渲染的隐藏表格
本文详解了如何使用Python与Selenium结合代理IP技术,从金融网站(如东方财富网)抓取由JavaScript渲染的隐藏表格数据。内容涵盖环境搭建、代理配置、模拟用户行为、数据解析与分析等关键步骤。通过设置Cookie和User-Agent,突破反爬机制;借助Selenium等待页面渲染,精准定位动态数据。同时,提供了常见错误解决方案及延伸练习,帮助读者掌握金融数据采集的核心技能,为投资决策提供支持。注意规避动态加载、代理验证及元素定位等潜在陷阱,确保数据抓取高效稳定。
166 17
|
6月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
6月前
|
存储 JavaScript 前端开发
全网最全情景,深入浅出解析JavaScript数组去重:数值与引用类型的全面攻略
如果是基础类型数组,优先选择 Set。 对于引用类型数组,根据需求选择 Map 或 JSON.stringify()。 其余情况根据实际需求进行混合调用,就能更好的实现数组去重。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
6月前
|
消息中间件 JavaScript 前端开发
最细最有条理解析:事件循环(消息循环)是什么?为什么JS需要异步
度一教育的袁进老师谈到他的理解:单线程是异步产生的原因,事件循环是异步的实现方式。 本质是因为渲染进程因为计算机图形学的限制,只能是单线程。所以需要“异步”这个技术思想来解决页面阻塞的问题,而“事件循环”是实现“异步”这个技术思想的最主要的技术手段。 但事件循环并不是全部的技术手段,比如Promise,虽然受事件循环管理,但是如果没有事件循环,单一Promise依然能实现异步不是吗? 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您
|
10月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
266 17
|
6月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
615 29

推荐镜像

更多
  • DNS