博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js中浅拷贝和深拷贝以及深拷贝的实现
阅读量:4981 次
发布时间:2019-06-12

本文共 2582 字,大约阅读时间需要 8 分钟。

前言:2019年的第一篇分享...

一、什么是基本类型值和引用类型值?

ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型。
基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象。
当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值。

注:要了解深拷贝和浅拷贝,首先要先理解ECMAScript中的数据类型,其中基本类型值(如undefined、null、number、string、boolean以及es6新增的Symbol), 还有一些引用类型值(如对象)。

  浅拷贝和深拷贝一般是对于引用类型值(如对象)来讲的,而基本类型值,只要是复制,就一定是另开辟以存储空间。

 

1 // 示例1(基本类型值))2 var a = 10;3 var b = a;4 b = 20;5 console.log(b); //输出 206 console.log(a); //输出 10 // 类似示例1,基本类型在拷贝的时候,b改变了,但是并不会印象到a。
1 // 示例2(引用类型值)2 var obj_a = { a: 10, b: 20 };3 var obj_b = obj_a;    4 obj_b.a = 30;5 console.log(obj_b); //输出 { a: 30, b: 20 }6 console.log(obj_a); //输出 { a: 30, b: 20 }7 8 // 类似示例2,复杂类型在拷贝的时候,然后改变了obj_b的属性的值,但是却改变了obj_a的,很明显,这个结果并不是我们想要的,其实他们还是指向同一个对象,只是展示窗口的位置不同而已。
1 // 示例3(应用类值&深拷贝)2 var obj_a = { a: 10, b: 20, c: 30 };3 var obj_b = { a: obj_a.a, b: obj_a.b, c: obj_a.c };4 obj_b.a = 40;5 console.log(obj_b); //输出 { a: 40, b: 20, c: 30 }6 console.log(obj_a); //输出 { a: 10, b: 20, c: 30 }7 8 // 类似示例3,复杂类型在拷贝的时候,然后改变了obj_b的属性的值,但是却没有改变了obj_a的,因为在拷贝的时候,其实是相当于新建了一个领地,然后遍历旧对象的每一项的值,在新对象里面新建每一项,然后把对应的值复制进去,他们是不同的对象,这就是所谓的深拷贝。

 

二、浅拷贝和深拷贝的原理
1.基本数据类型值( 基本数据类型值的名和值都存在栈内存里面 ) 如:let a = 1; 如图:

 

  当let b = a,b复制了a,栈内存会另外开辟一块地方存放b的名值,如图:

   

 两者互不干涉,谁也没有影响到谁。

2.引用数据类型值( 引用数据类型值栈内存里面存值的位置则存放的是a的值在堆内存里面的位置,也就是唯一堆地址 )
如:let a = [ 0, 1, 2, 3, 4 ];如图:
当let b = a,b复制了a,b引用了a的堆地址。如图:

  

所以这个时候,改变了b,a也会受到影响。
 
三、实现深拷贝
层级拷贝,递归方式(其实就是函数的自我调用)
何为层级?如,var a = [0,1,[3,4],3];数组嵌套着数组。

 实现方法:

// 代码中加入判断,当碰到数组、对象等时递归函数  1 function deepClone(obj){ 2         //定义对象来判断当前的参数是数组还是对象 3         let objClone = Array.isArray(obj)?[]:{}; 4         //如果obj存在并且为对象         5         if(obj&&typeof obj == "object"){ 6             for(let key in obj){ 7                 if(obj.hasOwnProperty(key)){ 8                     //如果obj的子元素为对象,那么递归(层级遍历) 9                     if(obj[key]&&typeof obj[key] == "object"){10                         objClone[key] = deepClone(obj[key]);11                     }else{12                     //如果不是,直接赋值13                         objClone[key] = obj[key];14                     }15                 }16             }17         }    18         return objClone;19     }

 

利用 浅拷贝&深拷贝

注:deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
  target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
  object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

 
1 let a = [0, 1, [2, 3], 4],2    b = $.extend(true, [], a);3 a[0] = 1;4 a[2][0] = 1;5 console.log(a, b);
通过ES6的  方法
用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
 
1 var a  = [1,2,3]2 var b = a.concat();3 b[2] =10;4 console.log(a

上面这个情况a的值并没有改变。

以上就是我的一些个人的理解和靖藏使用的一些深拷贝的处理方法,仅供参考。

转载于:https://www.cnblogs.com/it-xiong/p/10476940.html

你可能感兴趣的文章
Java EE 学习(2):使用 IDEA 开发 最简java web
查看>>
Linux扩展权限
查看>>
面向对象【林老师版】:多态与多态性(十三)
查看>>
PHP--------TP中的ajax请求
查看>>
sync framework参考收集系列
查看>>
PHP-----正则表达式
查看>>
spring中bean生命周期
查看>>
Java Service Provider Interface
查看>>
对象的生命周期
查看>>
【DL】模型蒸馏Distillation
查看>>
iOS:为什么TCP连接要三次握手,四次挥手
查看>>
将博客搬至CSDN
查看>>
Mysql查询某字段重复值并删除重复值
查看>>
使用python获取微医数据
查看>>
使用pyinstaller 打包python程序
查看>>
ubuntu 上开发.netcore
查看>>
小程序索引列表排序
查看>>
vue使用video.js解决m3u8视频播放格式
查看>>
前端H5与安卓和ios之间通信
查看>>
7-7
查看>>