ES6的解构赋值是深拷贝or浅拷贝?

2021-05-25

3695 1 0

面试时候有面试官问到ES6的解构赋值是深拷贝还是浅拷贝?,这里做一个总结.

ES6的解构赋值,大家应该都清楚,就是可以快速取出数组或者对象中的值;我们先来看一个使用案例:

解构赋值

更多的解构赋值知识可以查看: https://es6.ruanyifeng.com/#docs/destructuring

那么,ES6的解构赋值到底是深拷贝还是浅拷贝呢?

我们先来看一下深拷贝和浅拷贝的定义

深拷贝:修改新变量的值不会影响原有变量的值。默认情况下基本数据类型(number,string,null,undefined,boolean)都是深拷贝。

浅拷贝:修改新变量的值会影响原有的变量的值。默认情况下引用类型(object)都是浅拷贝。

我们先开看一个基本类型,直接用等号赋值的例子

1let user = 'siri' 2let stu = user 3stu = 'jack' 4console.log('输出:',stu) 5// 输出:jack 6console.log('输出:',user) 7// 输出:siri 8

由上方的例子可以知道: stu的数值改变并不会影响user ,所以基本数据类型,直接用等号赋值,也都是深拷贝;

我们再看一个引用类型,直接用等号赋值的例子

1let obj1 = { 2 name:'siri', 3 age:18 4} 5let obj2 = obj1 6 7obj2.name = 'jack' 8console.log('obj1',obj1) 9console.log('obj2',obj2) 10// obj1 {name: "jack", age: 18} 11// obj2 {name: "jack", age: 18} 12

打印信息

上方例子中我们可以看到,obj1赋值给obj2,然后改变obj2中的name值,发现obj2中的name也跟随着改变了,所以是浅拷贝。(因为他们引用的是同一个地址的数据!拷贝的时候并没有给obj2创造独立的内存,只是把obj1指向数据的 指针 拷贝给了obj2)

上方的例子了解了之后 我们再回到解构赋值

修改最上方的解构赋值代码,给name 和 age赋值

1const userInfo = { 2 name:'siri', 3 age:18 4} 5let {name,age} = userInfo 6name = 'jack' 7age = 16 8console.log('打印userInfo',userInfo) 9// 打印userInfo {name: "siri", age: 18}

 我们发现userInfo 的数据并没有被改变,有同学会说,解构赋值好像是深拷贝啊????? image.png

我们再修改一下代码看看

1const userInfo = { 2 name:'siri', 3 age:18, 4 detail:{ 5 qq:'1', 6 email:'1366666@163.com' 7 } 8} 9let {name,age,detail} = userInfo 10name = 'jack' 11age = 16 12detail.qq = "2" 13console.log('打印userInfo',userInfo) 14

打印信息:

打印结果

 发现解构赋值出来的对象将原对象detail中的qq的数据修改了,这样看还是浅拷贝;

###总结:

  • 解构赋值,如果所解构的原对象是一维数组或对象,其本质就是对基本数据类型进行等号赋值,那它就是深拷贝;

  • 如果是多维数组或对象,其本质就是对引用类型数据进项等号赋值,那它就是浅拷贝;

结论:解构赋值是浅拷贝(因为它确实不能对多维数组或对象达到深拷贝的作用);

深拷贝的实现方法

本质还是将对象拆开为基本数据类型进行赋值。

1function deepClone(source){ 2 const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象 3 for(let keys in source){ // 遍历目标 4 if(source.hasOwnProperty(keys)){ 5 if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下 6 targetObj[keys] = source[keys].constructor === Array ? [] : {}; 7 targetObj[keys] = deepClone(source[keys]); 8 }else{ // 如果不是,就直接赋值 9 targetObj[keys] = source[keys]; 10 } 11 } 12 } 13 return targetObj; 14}
点赞
收藏

评论区

加载中...

相关推荐

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java 复制Map对象(深拷贝与浅拷贝)

java复制Map对象(深拷贝与浅拷贝)CreationTime2018年6月4日10点00分Author:Marydon1.深拷贝与浅拷贝  浅拷贝:只复制对象的引用,两个引用仍然指向同一个对象

也谈JavaScript浅拷贝和深拷贝

网上关于这个话题,讨论有很多了,根据各路情况我自己整理了一下,最后还是能接近完美的实现深拷贝,欢迎大家讨论。javascript中的对象是引用类型,在复制对象的时候就要考虑是用浅拷贝还是用深拷贝。直接赋值对象是引用类型,如果直接赋值给另外一个对象,那么只是赋值一个引用,实际上两个变量指向的同一个数据对象,如果其中一个对象的属性变更,那么另外一个也会变更。示

带你了解JS对象的浅拷贝和深拷贝

以下主要介绍了正常情况下的拷贝、浅拷贝、深拷贝三种方式的区别。正常拷贝:复制一个对象,它们的内存地址是相同的浅拷贝:拷贝对象的第一层属性深拷贝:拷贝对象多层的属性正常拷贝假设我们要复制一个对象,如果不对其进行深拷贝,那么改变其中一个对象后,另外一个对象也会

python 赋值引用 浅拷贝 深拷贝

一、基础概念1、直接赋值:其实就是对象的引用(别名)。2、浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。3、深拷贝(deepcopy):copy模块的deepcopy方法,完全拷贝了父对象及其子对象。二、代码示例importcopya1,2,3,4,'a','b'原始对象ba

实现深拷贝的多种方式

实现深拷贝的多种方式简单来说,深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。1.简单深拷贝(一层浅拷贝)①for循环拷贝//只复制第一层的浅拷贝javascriptfunc