javaScript实现浅拷贝和深拷贝的方法有哪些?看这一篇就够了(详细)

javaScript实现浅拷贝和深拷贝的方法有哪些?看这一篇就够了!

这篇文章主要整理区分哪些方法实现的是浅拷贝,哪些方法是实现的是深拷贝,所以对于深拷贝和浅拷贝的概念不进行过多赘述(简单描述就是深拷贝是多层拷贝,浅拷贝是一层拷贝),直接进入正题:

实现浅拷贝方法:

1. 循环遍历赋值:

这里以for循环为例:
在这里插入图片描述
循环赋值后,输出newArr数组内容跟arr一模一样,接下来我们验证一下该方法实现的是深拷贝还是浅拷贝:
在这里插入图片描述
可以看到,循环赋值结束,我明明改变的是arr数组中的对象里面a的值为4,输出的newArr数组里面的对象a的值也跟着改变了,由此可以得出结论for循环赋值方法实现的是浅拷贝。

同理for…in…/for…of…/forEach循环赋值实现的同样也都是浅拷贝,有兴趣同学的可以自己私底下试一下。

2. 数组(Array)方法:
js里面数组有很多操作方法,细心的同学可能早就注意到了,很多数组方法稍微变通一下,就可以实现拷贝功能,只是纠结拷贝模式是深拷贝还是浅拷贝,这里给大家整理了一下可以实现拷贝的数组方法。

①concat(合并数组,返回新数组):空数组和需要拷贝的数组合并,返回新数组实现拷贝;
在这里插入图片描述
②slice(返回截取指定位置的子数组):从0索引开始截取,返回全新数组实现拷贝;
在这里插入图片描述
③Array.from(ES6新增:类数组对象或者可遍历对象转换成一个真正的数组):
在这里插入图片描述④Array的遍历语法都可以实现拷贝forEach/map(使用指定函数遍历数组,返回映射新数组)/filter(使用指定函数遍历过滤数组,返回过滤结果新数组),原理相同于循环遍历法。
检验一下:
在这里插入图片描述
改变了原数组arr中对象数据a的值为5,数组方法进行拷贝的值全部跟着改变了,因此可以验证数组方法对数组进行的拷贝都是浅拷贝。
3. 对象的assign方法:
object.assign方法是用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)上,类似于数组的concat方法。因此我们可以将原对象与一个空对象进行合并,生成一些新的对象实现拷贝。
在这里插入图片描述
我们尝试修改一下obj对象里面的数组c和对象d属性看一下:
在这里插入图片描述
可以看到,修改了obj中数组和对象数据,newObj里面对应的值也发生了改变,因此也验证了利用Object.assign()方法进行的拷贝也是浅拷贝。
4. JQuery.$extend():第一个参数设置false或者不加则为浅拷贝
$.extend(true,{},a,b)
true:是否深度拷贝,不加为false,浅拷贝,加了深拷贝
{}:将合并结果保存到新对象,这样原对象将不会发生改变
a:第一个合并的对象
b:第二个合并的对象

实现深拷贝的方法:

1.循环递归:通过上面验证我们知道,普通循环赋值是为浅拷贝,追其原因是因为拷贝的过程中遇到了对象类型然后只拷贝了对象的指向。所以循环递归的原理就是循环的过程中判断值的类型,如果为对象类型,则在对象类型的数据里面进行进一步循环赋值,直到循环对象里面没有对象类型的数据为止。
在这里插入图片描述
这个递归函数的原理就是先定义一个空对象newObj用来接收复制后的实例,将newObj和需要深拷贝的对象obj传入函数deepClone,函数内部通过循环赋值的方法将obj对象的值赋值给newObj,不同的是循环赋值前先判断当前值的类型是否为数组(Array)或者对象(Object)这种引用类型的值,如果是这两种引用类型的值,递归进deepClone继续进入循环赋值,直到所有的值都是基础数据类型为止,所以,这种赋值过来后的复制对象里面全是基础数据类型的数据,不存在引用类型,从而不管如果改变原对象(obj),对新对象(newObj)都不会产生任何影响。
如图:改变原对象obj里面的数组和对象值,newObj里面对应位置的值不会产生改变,可以证明obj和newObj是完全独立的两个对象

2.JSON.parse(JSON.stringfy(X))
我们都知道,利用JSON.stringify可以将JS对象转化成JSON字符串;利用JSON.parse方法可以将JSON字符串转化成JS对象。因此我们可以试一下用JSON方法实现拷贝的效果:
在这里插入图片描述
利用JSON的方法可以看出来,修改了obj和的数组和对象值,newObj的对应位置的值没有发生改变,因此可以证明利用JSON的stringify和parse方法是可以很快捷的实现深拷贝。
细心的同学可能已经发现了,newObj里面缺少了一些东西,obj里面的undefined值在newObj里面丢失了,因此我去查了一下,看看用JSON方法还有哪些局限性,整合了网上的答案,这里整理给大家:
①如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
②如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null;
③JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
④如果对象中存在循环引用的情况也无法正确实现深拷贝;
⑤如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象;
⑥如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式;

3. JQuery.$extend():第一个参数设置true;
$.extend(true,{},a,b)
true:是否深度拷贝,不加为false,浅拷贝,加了深拷贝
{}:将合并结果保存到新对象,这样原对象将不会发生改变
a:第一个合并的对象
b:第二个合并的对象

海龟先生233
关注 关注
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript数组深拷贝浅拷贝的两种方法
01-21
例如这个例子: 代码如下:var arr = [“One”,”Two”,”Three”];var arrto = arr;arrto[1] = “test”;[removed]ln(“数组的原始值:” + arr + “<br>”);//Export:数组的原始值:One,test,Three[removed]ln(“数组的新值:” + arrto + “<br>”);//Export:数组的新值:One,test,Three 像上面的这种直接赋值的方式就是浅拷贝,很多时候,这样并不是我们想要得到的结果,其实我们想要的是arr的值不变,不是吗? 方法一:js的sli
JavaScript基础心法 深浅拷贝(浅拷贝深拷贝)
12-09
说到深浅拷贝,必须先提到的是JavaScript的数据类型,之前的一篇文章JavaScript基础心法——数据类型说的很清楚了,这里就不多说了。 需要知道的就是一点:JavaScript的数据类型分为基本数据类型和引用数据类型。 ...
JS深拷贝浅拷贝 和 使用场景 详解
沐枫
10-24 8201
当对某个数据(数组或对象)进行拷贝后,修改新数据(拷贝后的数据)里面第1层的数据是不会影响老数据(被拷贝的数据)的,但是如果还要第2层 或 更深层次的数据(复杂数据类型),它仍然是有关联的,如果修改了新数据,那么老数据也会被修改。表示传递的是变量所在的内存地址【内存地址:也就是所谓的指针】(就是当一个变量的值 赋给 另一个新变量的时候,新变量修改了值,那么原来变量的值也会被修改,因为它们是同一个内存地址,所以一改全改)比如:想对某个数组 或 对象的值进行修改,但是又想保留原来数组 或 对象的值不被修改!
JS中的深拷贝实现方式
最新发布
为技术而生
04-26 299
以上就是几种常见的JS深拷贝实现方式。在实际使用中,我们需要根据具体的需求和场景选择合适的方式。同时,我们也要注意深拷贝可能带来的性能问题,因为深拷贝需要复制对象的所有子对象,如果对象很大,那么深拷贝可能会消耗大量的内存和时间。
JavaScript浅拷贝(三种方法)
weixin_46022934的博客
11-20 2926
浅拷贝实现方法(三种) 提示: JavaScript中的深浅拷贝实现方法(三种) 文章目录深浅拷贝实现方法(三种)前言一、如下图所示(图片非自己制作)二、深拷贝方法实现(三种方法)1.通过递归的方式实现深拷贝(jquery中的extend)2.使用JSON.parse()和JSON.stringify()3.通过递归的方式实现深拷贝 前言 基本数据类型:数据存储在栈中。 引用数据类型:数据存放在堆内存中,栈中存放了一个引用地址,指向堆内存中的数据。 引用数据赋值,a 在栈区中,使用了 *b *
总结一下js浅拷贝深拷贝
忧郁的蛋的专栏
06-10 1469
对于对象中有对其他对象的引用,可以使用 WeakMap 来存储已经复制过的对象。是将一个对象的值复制给另一个对象,但如果对象中包含对其他对象的引用,则这些引用仍然指向原来的对象。这是使用 WeakMap 的一种示例,这个示例的深拷贝函数递归地复制对象,但检查 WeakMap 中是否已经存在该对象的副本,如果存在则直接使用副本,而不是重新创建。需要注意的是,使用构造函数复制内置对象类型只适用于部分内置对象类型,对于其他的内置对象类型,可能需要使用其他的方法来进行复制,或者使用第三方库来进行复制。
详解js中的浅拷贝深拷贝
DZQ1223的博客
05-30 3491
栈(stack):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;堆(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表浅拷贝就是只拷贝基础数据类型的数据,并且数据只有单一的一层,而深拷贝用于拷贝具有复杂的数据类型的数据。
JS深拷贝浅拷贝
qq_50797036的博客
10-13 1727
JS深拷贝浅拷贝
javascript】详解javaScript深拷贝
weixin_33862993的博客
08-14 470
      前言: 最开始意识到深拷贝的重要性是在我使用redux的时候(react + redux), redux的机制要求在reducer中必须返回一个新的对象,而不能对原来的对象做改动,事实上,当时我当然不会主动犯这个错误,但很多时候,一不小心可能就会修改了原来的对象,例如:var newObj = obj; newObj.xxx = xxx  实际上,这个时候newObj和obj两个...
javascript浅拷贝深拷贝的详解
11-27
下面小编就为大家带来一篇浅谈JavaScript中面向对象的的深拷贝浅拷贝。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。 1.浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。 ...
javascript二维数组和对象的深拷贝浅拷贝实例分析
12-13
这篇文章主要为大家详细介绍了js实现数组和对象的深浅拷贝, 1.浅拷贝: 将原对象或原数组的引用直接赋给新对象,新数组,新对象/数组只是原对象的一个引用 2.深拷贝: 创建一个新的对象和数组,将原对象的各项属性...
JavaScript基于遍历操作实现对象深拷贝功能示例
10-17
在实际应用中,JavaScript深拷贝还有其他实现方式,如使用 `JSON.parse` 和 `JSON.stringify`,但这种方法有局限性,因为它无法处理函数和循环引用。此外,还可以使用第三方库如 Lodash 的 `_.cloneDeep` 方法。...
浅谈JavaScript中面向对象的的深拷贝浅拷贝
10-21
下面小编就为大家带来一篇浅谈JavaScript中面向对象的的深拷贝浅拷贝。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
js浅拷贝深拷贝的几种方法
EvanJason的博客
11-15 1975
一个项目开发中经常会用到需要复制一个对象或者数组,但是却不能改变原始对象,所以就要用到拷贝,拷贝又分深拷贝浅拷贝,今天列举一下几种拷贝形式。 一、浅拷贝 (1) Object.assign() Object.assign我们经常会用到合并对象,当然利用Object.assign性质我们也可以实现对象的拷贝。 var obj1 = {a: 1, b: 2} var obj2 = Object.assign({}, obj1) obj2.a = 4 console.log(obj1, o
终于弄清楚JS深拷贝浅拷贝了-读这一篇就够
热门推荐
眼里长着太阳,笑里全是坦荡
07-27 3万+
今天,CVTE面试官问了深拷贝浅拷贝的问题 我的回答是:浅拷贝是拷贝了对象的引用,当原对象发生变化的时候,拷贝对象也跟着变化;深拷贝是另外申请了一块内存,内容和原对象一样,更改原对象,拷贝对象不会发生变化; 但是面试官给我说:浅拷贝是拷贝一层,深层次的对象级别的就拷贝引用;深拷贝是拷贝多层,每一级别的数据都会拷贝出来; 回来查了一下资料,并没有发现面试官说的这种关于深拷贝浅拷贝的说法,看了...
js 数组或对象浅拷贝深拷贝的几种方法
haogemr的博客
03-13 1万+
第一种 function deepClone(obj){ var str,newObj = obj instanceof Array? [] : {}; if(typeof obj !== 'object'){ return; }else if(window.json){ ...
js实现浅拷贝深拷贝
qq_48386796的博客
05-27 133
js实现浅拷贝深拷贝 浅拷贝 //在这里插入代码片 //1.封装一个函数 function clone(o){ let result = Reflect.ownKeys(o) //获取到对象上普通值和symbol //的值 result得到的是一个数组,每个数组元素都是对象的属性名 let newO = {} result.forEach(value => { if(o.hasOwnProperty(value)){ newO[value] = o[value]
JS浅拷贝的多种实现方式
VVVVV
08-03 247
浅拷贝 概念:拷贝引用类型的数据指针,拷贝前和拷贝后的数据结构指向同一块内存地址,增删改查会互相影响 通过for循环遍历 let obj2={}; for(let key in obj){ if(obj.hasOwnProperty(key)){ obj2[key]=obj[key]; } } 通过(…)扩展运算符 let obj2={...obj}; 深拷贝 概念:开辟一块新的内存空间,复制要拷贝的数据至新创建的内存空间,两个数据结构的增删改查互不干扰
JS浅拷贝的原理以及实现方法
zhang19951的博客
04-25 518
文章目录前言一、JS的数据类型以及他们的区别二、常见的浅拷贝方法1.浅拷贝2.深拷贝总结 前言 JS 的深浅拷贝是面试常问的一道题,实际做项目中也会经常遇到一些深拷贝的用法,或者有时候在使用VUE的双向数据绑定时,会发现不生效,可能就是因为没有进行深拷贝,不能改变传值过来的数据问题呢!!!!! 在理解什么是首先拷贝时,首先要清楚JS的数据类型有哪些 一、JS的数据类型以及他们的区别 JS 的数据类型主要有两种,分别为引用数据类型和基本数据类型两种。 1.常见的基本数据类型主要有:Num
js实现浅拷贝深拷贝方法
08-29
对于浅拷贝,可以使用以下几种方式实现: 1. 使用`Object.assign()`方法进行浅拷贝: ```javascript const obj = { name: 'John', age: 25 }; const copy = Object.assign({}, obj); ``` 2. 使用展开运算符进行浅拷贝: ```javascript const obj = { name: 'John', age: 25 }; const copy = { ...obj }; ``` 3. 使用`Array.prototype.slice()`方法浅拷贝数组: ```javascript const arr = [1, 2, 3, 4, 5]; const copy = arr.slice(); ``` 对于深拷贝,可以使用以下几种方式实现: 1. 使用`JSON.parse(JSON.stringify())`方法进行深拷贝(注意该方法有一些限制): ```javascript const obj = { name: 'John', age: 25 }; const copy = JSON.parse(JSON.stringify(obj)); ``` 2. 使用递归实现深拷贝: ```javascript function deepClone(obj) { if (typeof obj !== 'object' || obj === null) { return obj; } let clone = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { clone[key] = deepClone(obj[key]); } } return clone; } const obj = { name: 'John', age: 25 }; const copy = deepClone(obj); ``` 需要注意的是,以上方式在处理一些特殊情况(如循环引用、函数、正则表达式等)时可能会存在一些问题,需要根据具体需求进行适当的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • javaScript实现浅拷贝和深拷贝的方法有哪些?看这一篇就够了(详细) 2975
  • linux发布vue程序步骤(个人笔记) 2265
  • javaScript 手写代码系列----防抖和节流 715
  • JavaScript 中NEW关键字原理+实现 559
  • JS的运行机制和事件循环及相关拓展(个人笔记) 209

最新评论

  • JS的运行机制和事件循环及相关拓展(个人笔记)

    前端小刘不怕牛牛: 优质文章必须支持

大家在看

  • c++ STL深度探索之迭代器(算法和容器之间的桥梁) 27
  • 说明:unity三维游戏源码:基础实例1:人物移动、连接数据库、对话
  • 优化算法—— 梯度下降(Gradient Descent)
  • 36.远程注入到入口点注入
  • 基于Springboot的在线政务服务中心系统万字文档PPT源码分享

最新文章

  • JS的运行机制和事件循环及相关拓展(个人笔记)
  • 执行上下文、this和call/apply/bind函数 (个人笔记)
  • linux发布vue程序步骤(个人笔记)
2022年6篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司爱联网站推广工具石岩百度网站优化大浪网页制作宝安建网站木棉湾网络广告推广大运模板制作西乡推广网站横岗设计公司网站丹竹头网站关键词优化木棉湾SEO按天扣费盐田设计网站民治网站优化按天扣费沙井网站制作大运企业网站建设光明设计网站木棉湾营销型网站建设平湖阿里店铺托管坪山网站建设设计东莞网站设计罗湖SEO按效果付费坑梓网页设计宝安网站优化排名大浪品牌网站设计南联网站排名优化龙华外贸网站设计松岗网站优化推广松岗网络广告推广布吉企业网站建设南山外贸网站设计民治英文网站建设歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化