js对象的深度克隆代码实现,js深克隆和浅克隆的区别

在讲JavaScript(js)深度克隆之前,我们先来了解一下js中对象的组成。 js中,每一个实例都是一个对象,具体分为:

原始类型

配置类型

原始类型

对象是指按值传递的Unknown 、 Null 、 Boolean 、 Number 和String 。

配置类型

对象指的是数组、对象和函数。这些是通过地址传递的。当传递时,它将是内存中的一个地址。

有两种类型的克隆或复制。

浅克隆

,

深度克隆

浅克隆

:基本类型按值传递,但对象仍然按引用传递。一种复制方法,其中复制数据的更改会影响原始数据。

深度克隆

:每个元素或属性都是完全复制的,并且完全独立于原始引用类型。这意味着即使稍后对象的属性发生更改,原始对象也保持不变。修改复制的数据是一种不影响原始数据的复制方法。

JS中的深拷贝和浅拷贝一直是一个热门话题。简而言之,复制涉及使用某种方法来生成与复制的数据(几乎)完全相同的数据。 JS,拷贝有两种:深拷贝(深克隆)和浅拷贝。

一个普遍的理解是,无论如何修改复制得到的数据,都不应该影响原始数据。例如,我们在日常生活中使用复制和粘贴,但我从未见过有人修改复制的Word文档。结果,原来的文件也被修改了。这个应该是从js内存空间开始的。

JS内存空间补充:JS内存空间由常量池、栈、堆组成。堆用于存储引用类型数据,例如数组和对象。这些都是引用类型数据。对象在内存空间中的存储格式如下。对象名和引用存储在栈空间中,引用指向堆空间中的对象。同样的事情也适用于数组。

我们都知道,当通过赋值操作或其他方法生成复制对象时,它实际上是原始对象,因为它只是对该对象的引用。如果修改一个新对象,其内容就是该对象的内容。原始对象也被修改。由于原对象与新对象的引用相同,因此就出现了深拷贝和浅拷贝的问题。

浅克隆(Shallow Copy) 如果数据类型是引用类型,给这个变量赋值实际上是指这个变量在内存中的地址。如下:

1.

直接赋值

如果数据类型是引用类型,给这个变量赋值实际上是指这个变量在内存中的地址。如下:

var obj={name: \’ccc\’,age: 18} //定义变量为对象,引用类型var cloneObj=obj //创建新变量并赋值console.log(cloneObj) //{name: \’ccc\’,age: 18} console.log(cloneObj===obj) //true2.

对象.assgin():

const arr1=[1, 2, 3]const arr2=Object.assign(arr1)arr2[0]=5console.log(arr1) //[5, 2, 3]console.log(arr2) //[5, 2, 3]3. Array.prototype.concat()(浅拷贝)

let arr=[1,2,3,4,{username:\’kebi\’,age:18}]; let arr1=arr.concat() //concat 是连接数组。如果不传参数,则复制以下数据: 4.目标数组的Array.prototype.slice()(浅拷贝)

let arr2=arr.slice(); //如果不传递参数,切片默认为all。

浅克隆带来的问题:

复制的数据不能包含函数,也不能被处理。复制的数据是参考,复制数据的更改会影响原始数据。深度复制(深度克隆),复制过程中会产生新的数据。更改不影响原始数据

var obj={name: \’ccc\’,age: 18} //定义变量为对象,引用类型var cloneObj=obj //创建新变量并赋值console.log(cloneObj) //{name: \’ccc\’,age: 18} console.log(cloneObj===obj) //trueobj.name=\’www\’console.log(cloneObj) //更改了{ name: \’www\’,age: 18 } 的属性值即可看到。 obj变量和cloneObj的属性值也发生了变化。原因是虽然它们是两个变量,但它们引用的变量是同一个变量。参见下面的图表分析。

深度克隆(深度复制) 1.

确定要复制的对象的类型

2.

它根据类型产生一个空对象或空数组,并且可以直接返回其他基本数据类型。

3.

调用for in方法遍历复制的对象(数组),并向新对象(数组)添加数据。如果是基本数据类型,直接添加到新的数组(对象)中。否则,深度克隆数据。子进度

递归

就是这样。

深克隆解决了浅克隆带来的问题。直接上代码。

function deepClone(o) { //判断是否不是引用类型,直接返回数据if (typeof o===\’string\’ || typeof o===\’number\’ || typeof o===\’ | boolean\’ | typeof o===\’unknown\’) { return o } else if (Array.isArray(o)) { //对于数组,定义一个新数组,复制完成后返回。此处不能使用数组,因为typeof 数组返回对象。 console.log(typeof []) //– object var _arr=[] o.forEach(item={ _arr.push(item) }) return _arr } else if (typeof o===\’object\’) { var _o={} for (let key in o) { _o[key]=deepClone(o[key]) } return _o }}var arr=[1, 2, 3, 5] var cloneArr=deepClone(arr)console. log(cloneArr) //– [ 1, 2, 3, 5 ]console.log(arr===cloneArr) //– falsevar obj={ name: \’ ccc\’,age: 18 }var cloneObj=deepClone(obj) console.log(cloneObj) //– { name: \’ccc\’,age: 18 }console.log(obj===cloneObj) //falseobj.name=\’www \’console.log (obj) //– { name: \’www\’,age: 18 }console.log(cloneObj) //– { name: \’ccc\’,age: 18 }obj和cloneObj各自指向自己的变量地址,代码注释互不影响。参见下图:

注:上图中的深度克隆代码仅供参考。有许多细节没有考虑到,例如数组和对象的嵌套副本。具体用法参见Lodash的cloneDeep()方法。

Json.parse(Json.Stringfy()) (深拷贝)

let arr3=JSON.parse(JSON.stringify(arr));//先将原数组转换为json字符串,改为base数据类型,完全生成新数据,然后转换为原数组js数组,利用这个实现深复制

本文和图片来自网络,不代表火豚游戏立场,如若侵权请联系我们删除:https://www.huotun.com/game/651004.html

(0)
上一篇 2024年5月29日
下一篇 2024年5月29日

相关推荐

  • 和平精英福利商店怎么兑换?

    和平精英福利商店怎么兑换? 可以通过活动集碎片到你到商店去兑换。   和平精英CPU兑换码? 康师傅兑换码:需要购买官方合作款的香辣牛肉面,然后用微信扫描料包上的二维码。在小程序“召唤空投”中可以获取军需礼包。 玛莎拉蒂兑换码:官网赠送钥匙兑换码,无法从其他平台获取,建议不要购买。 每个CDK仅支持使用一次,不可重复使用。 EMMMyxhjVHMA…

    3小时前
  • 和平精英注册怎么修改?

    和平精英注册怎么修改? 在设置里面有一个修改模式就可以 pupu怎么修改和平精英? 我们只需要打开pu pu,然后点击加载和平精英,然后我们再点击开始的这个按钮,就可以修改和平精英数据 和平精英怎么修改语音? 可以进入游戏内点背包,找到更换语音包的标志,选择自己喜欢的语音包更换 和平精英网名怎么修改? 1.首先要确认你有最少一张改名卡可以使用,才能改名字。 …

    游戏快讯 6小时前
  • 和平精英外放如何听脚步?

    和平精英外放如何听脚步? 在和平精英中,要听清敌人的脚步声非常重要。首先,要调整游戏音效的设置,确保脚步声的音量适中。 其次,要注意环境的影响,例如草地、沙地或水中的脚步声会有所不同。此外,要利用耳机来增强听觉效果,因为耳机可以更准确地定位敌人的位置。还可以通过观察队友的行动来判断敌人的位置,因为他们可能会听到敌人的脚步声。最重要的是要练习和培养自己的听觉感…

    游戏快讯 10小时前
  • 和平精英钢枪技巧? 和平精英钢枪技巧教学?

    和平精英钢枪技巧? 和平精英钢枪方法: 1、跳伞落点位置以及降落速度,优先比其他玩家落地捡枪是取得优势的关键,位置尽量选取靠边的敌方,不要腹背受敌,这样可以保证专心击退一个方向的敌人; 2、开镜的速度,优先比对方开镜瞄准射击,先发制人; 3、压枪水平,压枪稳定的玩家可以提高自己的爆头率,在对枪过程中率先击败敌人 和平精英钢枪技巧教学? 答,和平精英钢枪技巧教…

    游戏快讯 12小时前
  • 和平精英皮肤去哪里买可靠?

    和平精英皮肤去哪里买可靠? 可靠。淘宝上卖的和平精英玛莎拉蒂皮肤是真的的,你下单购买后,会直接把皮肤发送到你的游戏账号上的,这个完全不用担心的。因为我自己买过,朋友也买过,所以我觉得还挺靠谱,但是我建议你找淘宝销量高的,购买的人多的下单,也可以看看评价,看看差评,差评太多的就别买。自己脸黑的话,还是在淘宝买吧,毕竟吃鸡这个抽奖不好说啊 和平精英皮肤怎么查? …

    游戏快讯 13小时前