JS 深拷貝和淺拷貝概念,以及實現深拷貝的三種方式


一、理解堆棧,基本數據類型與引用數據類型

  1、堆棧

    棧(stack):系統自動分配的內存空間,內存會由系統自動釋放,用來存放函數的參數值,局部變量的值等,特點是先進后出。

    堆(heap):系統動態分配的內存,內存大小不一,內存不會自動釋放。一般由程序員分配釋放,主要負責像Obejct這種變量類型的存儲。

  2、基本數據類型

    概念:存放在棧內存中的簡單數據段,數據大小確定,內存空間大小確定。

    6種基本數據類型:Undefined、Null、Boolean、Number、String、Symbol

  3、引用數據類型

    概念:存放在堆內存中的數據,如對象、數組、函數等。名存在棧內存,值存在堆內存,棧內存會提供一個引用的地址指向堆內存中的值

 

二、深拷貝與淺拷貝

  1、淺拷貝

    概念:子對象復制父對象,父子對象發生關聯,兩者屬性值指向同一內存空間。簡單來講,就是改變其中一個對象,另一個對象也會跟着改變。

    舉例:

let a = [0,1,2],
     b = a;

a[0] = 3;

console.log(a,b) // [3,1,2] [3,1,2]
  2、深拷貝

     概念:拷貝對象各個層級的屬性。簡單的講,就是復制出來的每個對象都有屬於自己的內存空間,不會互相干擾。

 

三、實現深拷貝的幾種方式

  1、封裝深拷貝函數

function deepClone(obj) {
    let objClone = Array.isArray(obj) ? [] : {};
    if(obj && typeof obj === "object") {
        for(key in obj) {
            if(obj.hasOwnProperty(key)) {
                 // 判斷 obj 是否是對象,如果是,遞歸復制
                 if(obj[key] && typeof obj[key] === "object") {
                      objClone[key] = deepClone(obj[key]);
                 }else{
                      // 如果不是
                      objClone[key] = obj[key];
                 }
            }
        }
    }      
    return objClone
}         

let a = [1,2,3,4],
     b = deepClone(a);
a[0] = 5;
console.log(a,b)
   

 

2、借用JSON對象的 parse 和 stringify

function deepClone(obj){
    let newObj = JSON.stringify(obj);
    let objClone = JSON.parse(newObj);
    return objClone;  
}

let a=[0,1,[2,3],4],
    b=deepClone(a);
a[0]=1;
a[2][0]=1;
console.log(a,b);

 

原理:基本類型拷貝是直接在棧內存新開空間,直接復制一份名-值,兩者互不影響。
而引用數據類型,比如對象,變量名在棧內存,值在堆內存,拷貝只是拷貝了堆內存提供的指向值的地址,而JSON.stringify()巧就巧在能將一個對象轉換成字符串,也就是基本類型,那這里的原理就是先利用JSON.stringify()將對象轉變成基本數據類型,然后使用了基本類型的拷貝方式,再利用JSON.parse()將這個字符串還原成一個對象,達到了深拷貝的目的。

 

3、借用 JQ 的 extend 方法實現深拷貝。

  $.extend([deep], target, ...object);

  deep 表示深拷貝,Boolean

   target 目標對象

   ...object 需要進行合並的對象

 

 

本文是對於深淺拷貝的學習筆記整理記錄。感謝 聽風是風 博主的分享!
原文鏈接:https://www.cnblogs.com/echolun/p/7889848.html

 


免責聲明!

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



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