ES6的解構賦值與深拷貝和淺拷貝


昨天工作之中,前端伙伴討論到了解構賦值到底是淺拷貝還是深拷貝,今天梳理一下。

1、ES6的解構賦值,大家應該都清楚,就是可以快速取出數組或者對象中的值;具體使用情況如下:

const a = {
      name: 'name',
      age: 18,
      marriage: false,
    }

let { name, age, marriage} = a;
console.log(name, age, marriage) 
打印信息:name 18 false

2、明確一下深拷貝和淺拷貝的定義,或者說深拷貝和淺拷貝所應用於的數據類型。

深拷貝:修改新變量的值不會影響原有變量的值。默認情況下基本數據類型(number,string,null,undefined,boolean)都是深拷貝。
淺拷貝:修改新變量的值會影響原有的變量的值。默認情況下引用類型(object)都是淺拷貝。

其實你只要理解透徹了這兩句話就應該明白了解構賦值,甚至深拷貝的原理;

寫兩個例子,理解一下深拷貝和淺拷貝;

2.1 基本數據類型,直接用等號賦值,也都是深拷貝;

let a = 1;
let b = a;
b = 2;
console.log(a,b);
打印出:1,2

b的數值改變並不會影響a,所以基本數據類型賦值就是深拷貝;

2.2 引用類型,直接用等號賦值,是淺拷貝;

let a = {
    name: 'xiaoming'
};
let b = a;
b.name = 'zhangsan';

console.log(a)

打印:

 

 發現a的數據被b改變,所以是淺拷貝,為什么數據會被改變呢?

因為他們引用的是同一個地址的數據!拷貝的時候並沒有給b創造獨立的內存,只是把a指向數據的 指針 拷貝給了b!(不做延伸,感興趣的同學自行百度)

3、回到解構賦值,改一下最上面的例子。

const a = {
      name: 'name',
      age: 18,
      marriage: false,
    }

let { name, age, marriage} = a;

name = 'name1';
age = 20;
marriage = true;
console.log(a) 

打印:

 

 發現a的數據並沒有被改變,解構賦值好像是深拷貝啊?????

我們再改一下上面的例子看看:

const a = {
      name: 'name',
      age: 18,
      marriage: false,
      addr: { province: 'sichuan', city: 'chengdu' }
    }

let { name, age, marriage, addr } = a

name = 'myname'
age = 26
marriage = true
addr.province = 'shanghai'
addr.city = 'shanghai'

console.log(name, age, marriage, addr) 
console.log(a) 

打印:

 

 發現解構賦值出來的對象將原對象a中的addr的數據修改了,這樣看還是淺拷貝;

總結:解構賦值,如果所解構的原對象是一維數組或對象,其本質就是對基本數據類型進行等號賦值,那它就是深拷貝;

如果是多維數組或對象,其本質就是對引用類型數據進項等號賦值,那它就是淺拷貝;

最終的結論就是:解構賦值是淺拷貝(因為它確實不能對多維數組或對象達到深拷貝的作用);

4、最后我們再看一下深拷貝的本質:

深拷貝的實現方法:

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;
}

主要看這個:

它的本質還是將對象拆開為基本數據類型進行賦值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM