簡(jiǎn)單來說,深拷貝主要是將另一個(gè)對(duì)象的屬性值拷貝過來之后惜索,另一個(gè)對(duì)象的屬性值并不受到影響傻丝,因?yàn)榇藭r(shí)它自己在堆中開辟了自己的內(nèi)存區(qū)域赖晶,不受外界干擾。
? ? ? 淺拷貝主要拷貝的是對(duì)象的引用值腔长,當(dāng)改變對(duì)象的值袭祟,另一個(gè)對(duì)象的值也會(huì)發(fā)生變化。
? ? ? 我們看一個(gè)基本數(shù)據(jù)類型的列子捞附,let a = 1命令會(huì)在棧內(nèi)存中開辟一塊區(qū)域巾乳,之后拷貝一個(gè)a對(duì)象給b,如圖所示
? ? ? 我們可以看到鸟召,在棧內(nèi)存中也為b開辟了一塊內(nèi)存區(qū)域胆绊,此時(shí)a,b的賦值互不干擾欧募,當(dāng)改變a對(duì)象屬性值時(shí)b不受影響压状,這其實(shí)就完成了我們所謂的簡(jiǎn)單深拷貝,但并不能完全稱作深拷貝跟继,因?yàn)樯羁截惐旧砭歪槍?duì)的是復(fù)雜的Object類型數(shù)據(jù)种冬,并且深拷貝需要將屬性的各個(gè)層級(jí)都要拷貝過來,剛剛的例子只有一個(gè)層級(jí)舔糖。
? ? ? 我們開看一個(gè)js中的slice()方法娱两,這個(gè)方法其實(shí)并不能達(dá)到完全的深拷貝,
? ? ? 可以看到金吗,當(dāng)改變a[0]的值后十兢,打印處a的值改變?yōu)閇2,2,3,4],b的值并不受到影響辽聊,仍然是[1,2,3,4]纪挎,可以深拷貝成功,slice()這個(gè)方法表面上具有深拷貝的功能跟匆,但之后換一個(gè)多一層級(jí)別的數(shù)組异袄,
? ? ? ? ? ? 可以看出,slice()這個(gè)方法拷貝的并不徹底玛臂,一級(jí)屬性可以完全拷貝過來烤蜕,不受a改變的影響封孙,但是二級(jí)屬性還是沒能拷貝成功,仍然脫離不了a的控制讽营,說明slice根本不是真正的深拷貝虎忌。同理,concat方法與slice也存在這樣的情況橱鹏,他們都不是真正的深拷貝膜蠢,這里需要注意。說一下莉兰,JSON.stringify與JSON.parse可以實(shí)現(xiàn)深拷貝挑围。
接下來可以借引用數(shù)據(jù)類型來說一下淺拷貝,淺拷貝其實(shí)沒有什么特別之處糖荒,如圖所示
淺拷貝其實(shí)拷貝的是它的引用地址杉辙,let a = [0,1,2,3,4,5];? b = a;?
b拷貝了a在棧中的堆地址,都指向a在堆中的屬性值捶朵,當(dāng)a數(shù)組放生改變時(shí)蜘矢,b屬性值也會(huì)改變,因?yàn)閎也指向相同的堆內(nèi)存综看。