一、理解堆棧,基本數據類型與引用數據類型
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