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

• 阅读 2661

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

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

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

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

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

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

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

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

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

let user = 'siri'
let stu = user
stu = 'jack'
console.log('输出:',stu)
// 输出:jack
console.log('输出:',user)
// 输出:siri

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

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

let obj1 = {
  name:'siri',
  age:18
}
let obj2 = obj1

obj2.name = 'jack'
console.log('obj1',obj1)
console.log('obj2',obj2)
// obj1 {name: "jack", age: 18}
// obj2 {name: "jack", age: 18}

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

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

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

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

const userInfo = {
   name:'siri',
  age:18
}
let {name,age} = userInfo
name = 'jack'
age = 16
console.log('打印userInfo',userInfo)
// 打印userInfo {name: "siri", age: 18}

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

我们再修改一下代码看看

const userInfo = {
    name:'siri',
    age:18,
    detail:{
        qq:'1',
        email:'1366666@163.com'
    }
}
let {name,age,detail} = userInfo
name = 'jack'
age = 16
detail.qq = "2"
console.log('打印userInfo',userInfo)

打印信息:

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

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

###总结:

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

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

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

深拷贝的实现方法

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

function deepClone(source){
  const targetObj = source.constructor === Array ? [] : {}; // 判断复制的目标是数组还是对象
  for(let keys in source){ // 遍历目标
    if(source.hasOwnProperty(keys)){
      if(source[keys] && typeof source[keys] === 'object'){ // 如果值是对象,就递归一下
        targetObj[keys] = source[keys].constructor === Array ? [] : {};
        targetObj[keys] = deepClone(source[keys]);
      }else{ // 如果不是,就直接赋值
        targetObj[keys] = source[keys];
      }
    }
  }
  return targetObj;
}
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
2年前
java 复制Map对象(深拷贝与浅拷贝)
java复制Map对象(深拷贝与浅拷贝)CreationTime2018年6月4日10点00分Author:Marydon1.深拷贝与浅拷贝  浅拷贝:只复制对象的引用,两个引用仍然指向同一个对象
仔细看看,会有收获。js深浅拷贝
好好理解深浅拷贝和赋值(针对引用类型)赋值:两个对象指向同一内存地址。结果,无论是修改基本类型还是引用类型,两个对象的值都会改变。浅拷贝:两个对象指向不同的内存地址,但是他们中的引用类型数据指向同一内存地址。结果,修改引用类型,两个对象的值都会改变;修改基本类型,互不影响。深拷贝:两个对象指向不同的内存地址,他们中的引用类型也指向不同的内存地址。结果,均互不
晴空闲云 晴空闲云
2年前
也谈JavaScript浅拷贝和深拷贝
网上关于这个话题,讨论有很多了,根据各路情况我自己整理了一下,最后还是能接近完美的实现深拷贝,欢迎大家讨论。javascript中的对象是引用类型,在复制对象的时候就要考虑是用浅拷贝还是用深拷贝。直接赋值对象是引用类型,如果直接赋值给另外一个对象,那么只是赋值一个引用,实际上两个变量指向的同一个数据对象,如果其中一个对象的属性变更,那么另外一个也会变更。示
放学路上 放学路上
2年前
python 赋值引用 浅拷贝 深拷贝
一、基础概念1、直接赋值:其实就是对象的引用(别名)。2、浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。3、深拷贝(deepcopy):copy模块的deepcopy方法,完全拷贝了父对象及其子对象。二、代码示例importcopya1,2,3,4,'a','b'原始对象ba
Souleigh ✨ Souleigh ✨
3年前
实现深拷贝的多种方式
实现深拷贝的多种方式简单来说,深拷贝主要是将另一个对象的属性值拷贝过来之后,另一个对象的属性值并不受到影响,因为此时它自己在堆中开辟了自己的内存区域,不受外界干扰。浅拷贝主要拷贝的是对象的引用值,当改变对象的值,另一个对象的值也会发生变化。1.简单深拷贝(一层浅拷贝)①for循环拷贝//只复制第一层的浅拷贝javascriptfunc
菜园前端 菜园前端
12个月前
带你了解JS对象的浅拷贝和深拷贝
以下主要介绍了正常情况下的拷贝、浅拷贝、深拷贝三种方式的区别。正常拷贝:复制一个对象,它们的内存地址是相同的浅拷贝:拷贝对象的第一层属性深拷贝:拷贝对象多层的属性正常拷贝假设我们要复制一个对象,如果不对其进行深拷贝,那么改变其中一个对象后,另外一个对象也会
Wesley13 Wesley13
2年前
Java对象的浅拷贝和深拷贝&&String类型的赋值
Java中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、方法传参或返回值时,会有值传递和引用(地址)传递的差别。浅拷贝(ShallowCopy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,
Stella981 Stella981
2年前
JavaScript的深拷贝和浅拷贝
一、数据类型数据分为基本数据类型(String,Number,Boolean,Null,Undefined,Symbol)和对象数据类型。、1.基本数据类型的特点:直接存储在栈(stack)中的数据2.引用数据类型的特点:存储的是该对象在栈中引用,真实的数据放在堆内存里。引用数据类型在栈中存储了指针,该指针指向堆中该实
Wesley13 Wesley13
2年前
ES6新语法(二)
1.解构在ES6中,可以使用解构从数组和对象提取值并赋值给独特的变量,即将数组或对象中的值,拆成一个一个变量。解构:自动解析数组或对象中的值,并赋值给指定的变量。、1.1数组解构vararr3,4,5;vara,b,carr;
Stella981 Stella981
2年前
JavaScript基础心法——深拷贝和浅拷贝
!(https://oscimg.oschina.net/oscnet/c131215a5aaaeb7909d7398688df6ea6dcd.png)浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用,如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。前言说到深浅拷贝,必须先