上一章我們利用JSON.stringify()與JSON.parse()方法實(shí)現(xiàn)了深拷貝,但是這種方法存在很多弊端,如對(duì)象的屬性值是函數(shù)時(shí),無法拷貝;不能解決循環(huán)引用的問題;無法拷貝特殊對(duì)象,比如:RegExp、BigInt、Date、Set、Map等。這一章我們來詳細(xì)介紹一下深拷貝與淺拷貝。
首先要知道,js中數(shù)據(jù)類型分為基本數(shù)據(jù)類型 (Number, String, Boolean, Null, Undefined, Symbol)和對(duì)象數(shù)據(jù)類型 ( Object ),像 Array、Function、Date...等都屬于 Object,它們的值都是對(duì)象。
引用數(shù)據(jù)型在被創(chuàng)建時(shí),首先要在棧上給其引用分配一塊內(nèi)存,而對(duì)象的具體信息都存儲(chǔ)在堆內(nèi)存上,然后由棧上面的引用指向堆中對(duì)象的地址。當(dāng)尋找引用值時(shí),解釋器會(huì)先尋找棧中的地址。然后根據(jù)地址找到堆內(nèi)存的實(shí)體。
淺拷貝是會(huì)將對(duì)象的每個(gè)屬性進(jìn)行依次復(fù)制,但是當(dāng)對(duì)象的屬性值是引用類型時(shí),實(shí)質(zhì)復(fù)制的是其引用,當(dāng)引用指向的值改變時(shí)也會(huì)跟著變化。而深拷貝則是層層拷貝,會(huì)另外創(chuàng)造一個(gè)一模一樣的對(duì)象,新對(duì)象跟原對(duì)象不共享內(nèi)存。我們常用的拷貝數(shù)組的方法,如concat()、slice()、Array.from(),都是淺拷貝,除此之外,數(shù)組的其他方法如map()、filter()、reduce(),都是會(huì)造成淺拷貝的。
要實(shí)現(xiàn)淺拷貝,可以利用Object.assign方法或for in方法。
而上一章提到的實(shí)現(xiàn)深拷貝的方法,除了利用JSON.stringify()與JSON.parse()方法外,最好的辦法是利用遞歸實(shí)現(xiàn)??梢越鉀QJSON方法所遺留的弊端。