天天看點

淺析JS的深拷貝與淺拷貝

前言:

前段時間在做前端項目時,吃了深拷貝與淺拷貝的虧,今天就來整理一下這兩者的差別。

一、深拷貝VS淺拷貝

講到深拷貝與淺拷貝,我們先要弄清楚什麼是深拷貝,什麼是淺拷貝?

深拷貝:不僅拷貝對象的引用,同時也拷貝對象的實體,也就是它的位址。它将對象的所有層次都拷貝了。這樣進行深拷貝後兩個對象互相獨立,其中一個對象的改變不會影響到另一個對象。

淺拷貝:僅僅拷貝對象的引用,但是不拷貝對象的位址。它隻拷貝對象的第一層。這兩個對象的引用其實指向同一塊位址,相當于一個身份證ID的人有多個外号,而這些外号都是這一個人。這樣這些對象之間會互相影響,一個對象改變,其他也跟着改變。

淺析JS的深拷貝與淺拷貝

二、場景

基本類型對象指派:

var a = [1,2,3];
var b = a;
b.push(4); // b中添加了一個4
console.log(a); // a變成了[1,2,3,4]
           

自定義對象:

var obj = {number:125};
var obj2 = obj;
obj2.number = 126; // obj2.number改變了,
console.log(obj.number); // 126,obj的number跟着改變
           

這是因為javascript預設是淺拷貝,拷貝完之後的引用指向同一片位址,改變其中一個值,其他的值也會改變。

顯然淺拷貝将不同對象的

三、如何實作深拷貝

思路:指派隻能實作第一層的拷貝,我們遞歸拷貝對象的每一層。

function deepClone(obj){
  const objClone = Array.isArray(obj) ? [] : {}
  if (obj && typeof obj === 'object') {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) {
        // 判斷ojb子元素是否為對象,如果是,遞歸複制
        if (obj[key] && typeof obj[key] === 'object') {
          objClone[key] = this.deepClone(obj[key])
        } else {
          // 如果不是,簡單複制
          objClone[key] = obj[key]
        }
      }
    }
  }
  return objClone
  }
           

這樣即可實作深拷貝。

繼續閱讀