js数组和对象的深浅拷贝详解

本文主要为大家详细介绍js实现数组和对象的深浅拷贝,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望梦帮助到大家。

前提:原始数据类型和对象类型赋值时的差异

JavaScript的数据类型分为原始数据类型和对象类型。二者在内存中存放的方式不同,导致了其赋值时差异。分别举个栗子

var x = 1; var y = x; //y获得了和x同样的值 y = 2; console.log(x); // 1 var m = [1,2]; //m存放的是指向[1,2]这个数组对象的引用地址 var n = m; //n也获得 [1,2]数组对象的引用地址 n[0] = 3; console.log(m); //[3,2]

登录后复制

由上栗子可以看出 :原始数据类型赋值时,给的是实实在在的数据值 ,赋值后二者只是值一样而已,不会相互影响; 而对象类型,给的是 原数据的引用地址,所以新旧数据会互相影响,因为本质上还是同一个数据对象,如上栗中的数组 

什么是浅拷贝?

顾名思义,浅拷贝就是流于表面的拷贝方式;当属性值为对象类型时,只拷贝了对象数据的引用,导致新旧数据没有完全分离,还会互相影响。再举个栗子···

//测试数据var array1 = ['a',1,true,{name:'lei',age:18}]; //concat() slice() 实现浅拷贝var array2 = array1.concat() //修改拷贝后的数据array2[0] = 'b';      //array1[0]是原始数据类型 所以是直接赋值的array2[3].name = 'zhang';  //array1[3]是对象数据类型 所以拷贝的是对象的引用,其实还是和原数组使用同一对象 console.log(array1);  // ['a',1,true,{name:'zhang',age:18}]

登录后复制

  栗子中 array2是array1的浅拷贝对象,数组元素是原始数据类型的不会相互影响了(array1[0]),但是array1[3]是对象类型,还是会互相影响。

如何实现浅拷贝

上栗中的  array.concat()或者array.slice() 是特殊的实现数组浅拷贝的方式。

如何自己实现呢?遍历对象/数组的每个属性,然后赋值给一个新的对象不就行了么,如下实现

 //实现浅拷贝 function shallowCopy( target ){  if(typeof target !== 'object') return ;  //判断目标类型,来创建返回值  var newObj = target instanceof Array ? [] : {};   for(var item in target){   //只复制元素自身的属性,不复制原型链上的   if(target.hasOwnProperty(item)){    newObj[item] = target[item]   }  }   return newObj }  //测试  var test = [1,'a',{name:'lei',age:18}];  var copy = shallowCopy(test); console.log(copy[2].name);  //lei  copy[2].name = 'zhang'; console.log(test[2].name);  //zhang  原数据也被修改

登录后复制

深拷贝及其实现

  从浅拷贝解释基本可以明白,深拷贝就是 ‘完全’拷贝,拷贝之后新旧数据完全分离,不再共用对象类型的属性值,不会互相影响。

实现方式:

取巧方式 JSON.parse(JSON.stringify(Obj))  

var test = [1,'a',{name:'lei',age:18}]; var copy1 = JSON.parse(JSON.stringify(test)); //特殊方式 console.log(copy1); copy1[2].name = 'zhang'console.log(test);  //[1,'a',{name:'lei',age:18}] 未受到影响

登录后复制

注意:这种方式不能深拷贝有属性值为函数的对象,  可自行尝试

2. 实现深拷贝

    已经实现了浅拷贝,思考下应该是对 对象类型属性值赋值时,导致的没有完全分离,所以要修改下 拷贝对象类型属性值的方式,对它再调用一次深拷贝,这样就实现了深拷贝,如下:

//实现深拷贝function deepCopy( target ){ if(typeof target !== 'object') return ; //判断目标类型,来创建返回值 var newObj = target instanceof Array ? [] : {};  for(var item in target){  //只复制元素自身的属性,不复制原型链上的  if(target.hasOwnProperty(item)){   newObj[item] = typeof target[item] == 'object' ? deepCopy(target[item]) : target[item] //判断属性值类型  } }  return newObj} //测试var test = [1,'a',{name:'lei',age:18}]; var copy2 = deepCopy(test);copy2[2].name = 'zhang' console.log(test); ////[1,'a',{name:'lei',age:18}] 未受到影响

登录后复制

总结

一定要理解造成浅拷贝的原因:对象类型数据复制时,复制了引用地址,用的还是同一个数据对象;所以实现深拷贝的方式就是要对 对象类型属性值递归进行深拷贝,避免直接赋值。

相关推荐:

jQuery的$.extend浅拷贝与深拷贝实例解析

什么是js深拷贝和浅拷贝及其实现方式

在jquery中实现深拷贝与浅拷贝

以上就是js数组和对象的深浅拷贝详解的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2788012.html

(0)
上一篇 2025年3月8日 18:20:47
下一篇 2025年3月1日 08:36:25

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • JavaScript前端数据多条件筛选功能实现代码

    有时候也会需要在前端进行数据筛选,增强交互体验。当数据可用的筛选条件较多时,把逻辑写死会给后期维护带来很*烦。下面是我自己写的一个简单的筛选器,筛选条件可以根据数据包含的字段动态设置。本文主要为大家详细介绍了基于javascript实现前端…

    2025年3月8日
    200
  • JavaScript中重名的函数与对象解析

    在js中如果函数与对象重名了会怎么样?仔细详细这个问题值得讨论一下,本文主要给大家介绍了关于javascript中重名的函数与对象的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧啊,希望能帮助到大家。 JavaScript 允许重复声明…

    编程技术 2025年3月8日
    200
  • Node.js查询字符串querystring详解

    查询字符串模块提供了解析和格式化工具url查询字符串的api,本文将详细介绍关于node.js查询字符串解析querystring的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 一、querystring.pa…

    编程技术 2025年3月8日
    200
  • javascript实现求浮点数的平方根详解

    本文主要介绍javascript基于牛顿迭代法实现求浮点数的平方根,简单说明了牛顿迭代法的原理,并结合实例分析了javascript基于递归的数值运算相关操作技巧,需要的朋友可以参考下,希望能帮助到大家。 今天在网上看到一则利用牛顿迭代法求…

    编程技术 2025年3月8日
    200
  • Three.js利用dat.GUI简化试验流程

    dat.gui可以方便地向场景中添加控制条,随时调整参数。本文主要给大家介绍了关于three.js利用dat.gui如何简化试验流程的想内容,其实使用这个插件的最省事的地方在于,调试很方便的调节相关的值,从而影响最后绘制的结果。而dat.g…

    2025年3月8日
    200
  • Three.js实现阴影效果代码

    众所周知作为webgl的插件,three.js肯定没有原生webgl那样,添加一个阴影这么费劲。所以,经过一小时的研究(笨人不聪明,已经是极限速度了)。终于将阴影效果做了出来,并且还发现一些容易犯错的地方。话不多说了,来一起看看详细的介绍吧…

    2025年3月8日
    200
  • JavaScript实现页面中显示距离2018年中秋节的天数

    本文主要介绍使用javascript实现在页面中显示距离2018年中秋节的天数的相关资料,需要的朋友可以参考下,大家可以根据以下的代码思路进行实现自己的功能,希望能帮助到大家。 废话不多说了,具体代码如下所示: nbsp;html> …

    编程技术 2025年3月8日
    200
  • Three.js绘制字体模型示例代码

    本文主要给大家介绍了关于three.js如何绘制字体模型的相关资料,通过文中介绍的方法实现的效果非常的赞,需要的朋友可以参考借鉴,下面来一起看看吧。 首先你需要实例化 THREE.FontLoader() 来进行json格式的文字格式加载,…

    编程技术 2025年3月8日
    200
  • JS和jQuery注册信息的验证功能实现代码

    用js和jquery实现注册信息的验证功能的效果是一样的。本文通过实例代码给大家分享了基于js+jquery实现的注册信息验证功能,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友参考下吧,希望能帮助到大家。 HTML代码  请填写注册…

    编程技术 2025年3月8日
    200
  • vue-cli中的ESlint配置文件eslintrc.js介绍

    eslint是用来管理和检测js代码风格的工具,可以和编辑器搭配使用,如vscode的eslint插件。当有不符合配置文件内容的代码出现就会报错或者警告,本文主要和大家分享vue-cli中的eslint配置文件eslintrc.js详解 ,…

    编程技术 2025年3月8日
    200

发表回复

登录后才能评论