在了解js中深拷貝及淺拷貝之前先讓我們看一下js的棧內(nèi)存和堆內(nèi)存
棧內(nèi)存的六種數(shù)據(jù)類型:String Number Boolean undefined null Symbol;
堆內(nèi)存的三種數(shù)據(jù)類型: Object Array Function;
棧內(nèi)存:
let b = a;
a = 20
//console.log(a,b);a的值為20,b的值不變還是10
注: 棧內(nèi)存會開辟出一個(gè)新的空間存放數(shù)據(jù)场钉,因此當(dāng)a的值發(fā)生變化時(shí),b的值不會改let a = 10;
堆內(nèi)存:
let x= [1,3,4], y = x
x[0] = 5;? ?
?//console.log(x,y)? ? x的值為[5,3,4],y的值跟著改變?yōu)閇5,3,4]?
注:堆內(nèi)存數(shù)據(jù)的復(fù)制只是指向了同一個(gè)存放數(shù)據(jù)的地址,因此當(dāng)x值改變時(shí),y值也會改變
淺拷貝:
淺拷貝:簡單來講侄非,就是改變其中一個(gè)對象,另一個(gè)對象也會跟著改變
letx= [10,3,4], y = x
x[0] = 5;? ?
?//console.log(x,y)? ? x的值為[5,3,4]谬哀,y的值跟著改變?yōu)閇5,3,4]? ?
注:?y復(fù)制x比吭,x,y發(fā)生關(guān)聯(lián)绽族,兩者屬性值指向同一內(nèi)存空間。
深拷貝:
深拷貝:拷貝對象各個(gè)層級的屬性衩藤。簡單的講吧慢,就是復(fù)制出來的每個(gè)對象都有屬于自己的內(nèi)存空間,不會互相干擾赏表。
可用js中JSON.stringify()和JSON.parse()來?實(shí)現(xiàn) ----?深拷貝
?function deepClone(obj)
? ? ? ? ? ? ? ?{
? ? ? ? ? ? ? ?let newObj=JSON.stringify(obj)
? ? ? ? ? ? ? ?letcloneObj=JSON.parse(newObj)?
? ? ? ? ? ? ? ?return cloneObj
? ? ? ? ? ? ? ?}
letm= [1,2,3,[4,5]]? ? ? ??
n = deepClone(m)? ??
m[0] = 0;? ??
m[3][0] = 6;console.log(m,n)? ??
m的值為[0,2,3,[6,5]]娄蔼,n的值為[1,2,3,[4,5]]
深拷貝原理:
? ? ? ?基本類型拷貝是直接在棧內(nèi)存新開空間,直接復(fù)制一份名-值底哗,兩者互不影響岁诉。而引用數(shù)據(jù)類型,比如對象跋选,變量名在棧內(nèi)存涕癣,值在堆內(nèi)存,拷貝只是拷貝了堆內(nèi)存提供的指向值的地址前标,而JSON.stringify()巧就巧在能將一個(gè)對象轉(zhuǎn)換成字符串坠韩,也就是基本類型,那這里的原理就是先利用JSON.stringify()將對象轉(zhuǎn)變成基本數(shù)據(jù)類型炼列,然后使用了基本類型的拷貝方式只搁,再利用JSON.parse()將這個(gè)字符串還原成一個(gè)對象,達(dá)到了深拷貝的目的俭尖。