首页 > 其他分享 >js实现深拷贝和浅拷贝

js实现深拷贝和浅拷贝

时间:2022-12-19 16:44:31浏览次数:32  
标签:arr target 实现 js 对象 数组 var 拷贝

1,深拷贝与浅拷贝的区别

深拷贝:主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,它自己在堆中开辟了自己的内存区域,不受外界干扰。
浅拷贝:主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。

2,常见的实现对象的深拷贝方法:

1)JSON.parse( JSON.stringify() ) 序列化和反序列

 1 var obj = {
 2     a: '123',
 3     b: 234,
 4     c: true,
 5     d: null,
 6     e: function() {console.log('test')},
 7     h: new Set([4,3,null]),
 8     i:Symbol('fsd'),
 9     k: new Map([ ["name", "test"],  ["title", "Author"]  ])
10 }
11 console.log(JSON.stringify(obj)); 
12 // {"a":"123","b":234,"c":true,"d":null,"h":{},"k":{}}

可以看到data这个对象的属性里基本上包含了所有的数据类型,但通过JSON字符串化后,返回的值却有缺失,原因是JSON在执行字符串化的这个过程时,会先进行一个JSON格式化,获得安全的JSON值,因此如果是非安全的JSON值,就会被丢弃掉。其中undefined、function、symbol这三种类型的值就是非安全的(包括该对象的属性循环赋值该对象),所以格式化后,就被过滤掉了,而set、map这种数据格式的对象,也并没有被正确处理,而是处理成了一个空对象。

2)Object.assign(target, source1, source2)

es6新增的方法,可用于对象合并,将源对象的所有可枚举属性,复制到目标对象上。

 1 var obj = {
 2     a: '123',
 3     b: 234,
 4     c: true,
 5     d: null,
 6     e: function() {console.log('test')},
 7     h: new Set([4,3,null]),
 8     i:Symbol('fsd'),
 9     k: new Map([ ["name", "test"],  ["title", "Author"]  ])
10 }
11 var newData = Object.assign({},obj)
12 console.log(newData)

注意:当对象中只有一级属性,没有二级属性的时候,此方法为深拷贝,但是对象中有对象的时候,此方法,在二级属性以后就是浅拷贝

3)使用递归方法

 1 deepClone(target) {
 2     // 定义一个变量
 3     let result;
 4     // 如果当前需要深拷贝的是一个对象的话
 5     if (typeof target === 'object') {
 6        // 如果是一个数组的话
 7        if (Array.isArray(target)) {
 8             result = []; // 将result赋值为一个数组,并且执行遍历
 9             for (let i in target) {
10                 // 递归克隆数组中的每一项
11                 result.push(this.deepClone(target[i]))
12                 }
13             // 判断如果当前的值是null的话;直接赋值为null
14             } else if (target === null) {
15                result = null;
16                // 判断如果当前的值是一个RegExp对象的话,直接赋值    
17             } else if (target.constructor === RegExp) {
18                result = target;
19             } else {
20                // 否则是普通对象,直接for in循环,递归赋值对象的所有值
21                result = {};
22                for (let i in target) {
23                     result[i] = this.deepClone(target[i]);
24                    }
25             }
26     // 如果不是对象的话,就是基本数据类型,那么直接赋值
27     } else {
28         result = target;
29    }
30         // 返回最终结果
31         return result;
32 },

4)lodash函数库实现深拷贝

1 let clone = cloneDeep(obj)

3,常见的实现数组的深拷贝方法:

1)for循环实现

1 var arr = [1,2,3,4,5]
2 var arr2 = copyArr(arr)
3 function copyArr(arr) {
4     let res = []
5     for (let i = 0; i < arr.length; i++) {
6      res.push(arr[i])
7     }
8     return res

2)slice方法  原理:将原数组中抽离部分出来形成一个新数组。只要设置为抽离全部,即可完成数组的深拷贝

1 var arr = [1,2,3,4,5]
2 var arr2 = arr.slice(0)
3 arr[2] = 5
4 console.log(arr)
5 console.log(arr2)

注意:

①没有参数的时候,是拷贝数组
②一个参数的时候,拷贝从起始位置到数组末尾的元素
③两个参数的时候,拷贝从起始位置到 结束位置的元素(不包含结束位置的元素,含头不含尾)
一维数组元素是深拷贝,数组元素二维以上是值的引用

3)concat方法  原理:用于连接多个数组组成一个新的数组的方法。那么,只要连接它自己,即可完成数组的深拷贝

1 var arr = [1,2,3,4,5]
2 var arr2 = arr.concat()
3 arr[2] = 5
4 console.log(arr)
5 console.log(arr2)

注意只有在数组元素是一维的时候,是深拷贝,一维以上是对值的引用

4)ES6扩展运算符实现

1 var arr = [1,2,3,4,5]
2 var [ ...arr2 ] = arr
3 arr[2] = 5
4 console.log(arr)
5 console.log(arr2)

 

标签:arr,target,实现,js,对象,数组,var,拷贝
From: https://www.cnblogs.com/fxw1996/p/16992536.html

相关文章

  • 《“透视”个人大数据》项目开发小记 --(三)Android APP 开发(4)自定RelativeLayout实现通
       在开发项目的APP中,图片是重要表现形式,对图片进行适当的编辑(裁剪,设置聚光区,添加文字及图形标记等),可以增强图片的表现力。为了便于操作使用,APP中通过自定Relative......
  • vuejs处理树状结构的数据扁平化
    1,有这样一个数据:1data=[2{3"id":1,4"name":"吃喝",5"parentId":0,6"children":[7......
  • JavaScrip基础(一):JS基础认知
    JavaScript基础认知定义:是一种运行于JavaScript解释器/引擎中的解释型脚本语言什么是解释型?运行之前不不需要编译的,运行之前不会检查错误,知道碰到错误为止。解释型对应......
  • vuejs实现一键复制功能
    1,首先安装插件:npminstallclipboard--sava2,在组件中应用 importClipboardfrom'clipboard'3,clipboard的实际使用1<!--第一种直接绑定在按钮上-->2<bu......
  • aosp编译houdini实现兼容x86库
    title:aosp编译houdini实现兼容x86库date:2022-12-1914:12:36tags:阳性期间弄的这个东西,我头都大了首先我们自己弄一个combo仿照aospx86弄的在device/generic......
  • 基础算法汇总之二叉搜索树实现
    一.树定义在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层......
  • 日常总结:Vue实现一个炫酷的代码瀑布流背景
    先看一下效果:代码奉上:<template><canvasid="canvas"/></template><script>exportdefault{name:"BackCanvas",props:{height:{......
  • 基础算法汇总之AVL树实现
    一.什么是AVL树?在说AVL树之前,先回顾一下我们之前研究过的二分查找树(二分搜索树),在极端的情况下,二分搜索树会从一棵二叉树变为链表(按顺序插入数据)这样的查询效率会大打折扣。......
  • Flutter之导航栏骨架实现
    一、简介​​Flutter​​​是谷歌的移动​​UI​​​框架,可以快速在​​iOS​​​和​​Android​​上构建高质量的原生用户界面。​​Flutter​​​用​​Dart​​​作为......
  • Windows XP系统中实现远程关机和重启
    说明:我xp系统的机器名为: wwxpWindowsXP操作系统默认的安全策略中,只有管理员组的用户才有权从远端关闭或者重启计算机,一般情况下从局域网内其他电脑访问该计算机时,都只有......