摘要:前言里面淺拷貝和深拷貝是非常關(guān)鍵的知識(shí)點(diǎn),今天就來通過本文清楚的了解深淺拷貝以及該如何實(shí)現(xiàn)這兩種拷貝方式。對(duì)象的拷貝又分為淺拷貝和深拷貝。印證了上述所說的對(duì)于所有的基本類型,簡(jiǎn)單的賦值已經(jīng)是實(shí)現(xiàn)了深拷貝。
前言
JavaScript里面淺拷貝和深拷貝是非常關(guān)鍵的知識(shí)點(diǎn),今天就來通過本文清楚的了解深淺拷貝以及該如何實(shí)現(xiàn)這兩種拷貝方式。
深淺拷貝的區(qū)別拷貝:其實(shí)就是一個(gè)對(duì)象復(fù)制給另外一整個(gè)對(duì)象,讓對(duì)象相互不影響。對(duì)象的拷貝又分為淺拷貝和深拷貝。
對(duì)象的淺拷貝(只拷貝一層),所謂的淺拷貝,只是拷貝了基本類型的數(shù)據(jù),對(duì)于引用的類型數(shù)據(jù),復(fù)制后也是會(huì)發(fā)生引用,這種拷貝就叫做淺拷貝。
對(duì)象的深拷貝(拷貝多層),要求要復(fù)制一個(gè)復(fù)雜的對(duì)象,這就可以利用遞歸的思想來實(shí)現(xiàn),省性能又不會(huì)發(fā)生引用,它不僅將原對(duì)象的各個(gè)屬性逐個(gè)復(fù)制出去,而且將原對(duì)象各個(gè)屬性所包含的對(duì)象也依次采用深復(fù)制的方法遞歸復(fù)制到新對(duì)象上。
淺拷貝和深拷貝只針對(duì)object這樣的復(fù)雜的對(duì)象而深拷貝,因?yàn)閷?duì)于所有的基本類型,簡(jiǎn)單的賦值已經(jīng)是實(shí)現(xiàn)了深拷貝。
例子1.首先來讓我們思考一下以下的 a 應(yīng)該是多少?
顯而易見,a 是1。印證了上述所說的對(duì)于所有的基本類型,簡(jiǎn)單的賦值已經(jīng)是實(shí)現(xiàn)了深拷貝。我們可以簡(jiǎn)單地理解,這種b變了不影響a的就叫做深拷貝。
例子2.那么在這種情況下,a.name 又是多少呢?
*以下44為假設(shè),下同。
很明顯,a.name 是"b"。同樣我們可以簡(jiǎn)單地理解,這種b變了影響a的就叫做淺拷貝。
在例子2中,為什么 b 改變了會(huì)影響 a 呢?因?yàn)槲覀儍H僅是把堆里所記錄的地址44復(fù)制給了 b ,所以在后來我們對(duì) b.name 修改時(shí),會(huì)對(duì)44里記錄的 name 直接修改,當(dāng) a 再去引用的時(shí)候已經(jīng)是被修改過的44了。
我們想要在修改時(shí)候兩者互不影響,應(yīng)該是要像上圖一樣,創(chuàng)建一個(gè)新地址55,里面所包含的內(nèi)容和地址44一樣,這樣在修改時(shí)才會(huì)互不影響。同樣如果引用里還有引用,也要做到內(nèi)容一樣地址不一樣,只有兩者引用互無關(guān)聯(lián)才能做到互不影響,才能實(shí)現(xiàn)了深拷貝。
在了解了深淺拷貝的區(qū)別之后,我們想要實(shí)現(xiàn)深淺拷貝的話該怎么辦呢?
淺拷貝
1.ES6:object.assign()
var target = {a: 1, b: 1}; var copy1 = {a: 2, b: 2, c: {ca: 21, cb: 22, cc: 23}}; var copy2 = {c: {ca: 31, cb: 32, cd: 34}}; var result = Object.assign(target, copy1, copy2); console.log(target); // {a: 2, b: 2, c: {ca: 31, cb: 32, cc: 33}} console.log(target === result); // true
深拷貝
1.JSON.parse() 和 JSON.stringify()
var target = {a: 1, b: 1, c: {ca: 11, cb: 12, cc: 13}}; var targetCopy = JSON.parse(JSON.stringify(target)); targetCopy.a = 2; targetCopy.c.ca = 21; console.log(target); // {a: 1, b: 1, c: {ca: 11, cb: 12, cc: 13}} console.log(targetCopy); // {a: 2, b: 1, c: {ca: 21, cb: 12, cc: 13}} console.log(target === targetCopy); // false
可以看出通過JSON.parse() 和 JSON.stringify()我們可以很簡(jiǎn)單的實(shí)現(xiàn)了深拷貝,但是值得注意的是,JSON.parse() 和 JSON.stringify() 能正確處理的對(duì)象只有 Number、String、Array 等能夠被 json 表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)、Date等這種不能被 json 表示的類型將不能被正確處理。
2.判斷類型 + 遞歸拷貝(不可能復(fù)制__proto__)
function clone(object){ var object2 if(!(object instanceof Object)){ return object }else if(object instanceof Array){ object = [] }else if(object instanceof Function){ object = eval(object.toString()) }else if(object instanceof Object){ object = {} } for(let key in object){ object2[key] = clone(object[key]) } return object2 }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/106502.html
摘要:淺拷貝深拷貝淺拷貝的問題如果父對(duì)象的屬性等于數(shù)組或另一個(gè)對(duì)象,那么實(shí)際上,子對(duì)象獲得的只是一個(gè)內(nèi)存地址,而不是真正拷貝,因此存在父對(duì)象被篡改的可能。 淺拷貝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷貝: function deepCopy(p...
摘要:判斷是深拷貝對(duì)象還是數(shù)組如果要拷貝的對(duì)象的屬性依然是個(gè)復(fù)合類型,遞歸運(yùn)用遞歸,當(dāng)要拷貝的對(duì)象或者數(shù)組的屬性依然是個(gè)對(duì)象或者數(shù)組時(shí),遞歸調(diào)用。遍歷對(duì)象聊完了深拷貝和淺拷貝,接下來說一下遍歷。 在js這門語言中,數(shù)據(jù)存放在堆中,而數(shù)據(jù)的引用的存放在棧中。 淺拷貝 我們說的淺拷貝,指的是,引用地址的拷貝,棧中兩塊不同的引用地址都指向了堆中同樣一塊區(qū)域。所以,我們通過一個(gè)地址修改了堆中的數(shù)據(jù),...
摘要:定義淺復(fù)制如果復(fù)制引用,復(fù)制后的引用都是指向同一個(gè)對(duì)象的實(shí)例,彼此之間的操作會(huì)互相影響。淺復(fù)制數(shù)組淺復(fù)制利用數(shù)組方法和返回新數(shù)組特性,進(jìn)行復(fù)制。深復(fù)制對(duì)象深復(fù)制利用對(duì)象的和方法。 定義 淺復(fù)制 如果復(fù)制引用,復(fù)制后的引用都是指向同一個(gè)對(duì)象的實(shí)例,彼此之間的操作會(huì)互相影響。 深復(fù)制 深復(fù)制不是簡(jiǎn)單的復(fù)制引用,而是在堆中重新分配內(nèi)存,并且把源對(duì)象實(shí)例的所有屬性都進(jìn)行新建復(fù)制,以保證深復(fù)制的...
摘要:設(shè)計(jì)模式資源整理操作符小知識(shí)點(diǎn)實(shí)現(xiàn)發(fā)郵件功能數(shù)據(jù)結(jié)構(gòu)與算法資源整理跨域函數(shù)的合成與柯里化系列之防抖節(jié)流系列之正則系列之系列之系列之編碼系列之系列之操作符對(duì)象中的坐標(biāo)檢測(cè)對(duì)象或數(shù)組系列之機(jī)制系列之構(gòu)造對(duì)象系列之總結(jié)系列之淺復(fù)制與深復(fù)制系列之對(duì) Javascript設(shè)計(jì)模式資源整理JS操作符JS小知識(shí)點(diǎn)JS實(shí)現(xiàn)發(fā)郵件功能數(shù)據(jù)結(jié)構(gòu)與算法資源整理跨域函數(shù)的合成與柯里化JS系列之防抖節(jié)流JS系列...
摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 上一篇 JavaScript中的繼承 前言 文章開始之前,讓我們先思考一下這幾個(gè)問題: 為什么會(huì)有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實(shí)現(xiàn)淺拷貝與深拷貝 好了,問題出來了,那么下面就讓我們帶著這幾個(gè)問題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處...
閱讀 3979·2021-11-16 11:44
閱讀 5231·2021-10-09 09:54
閱讀 2039·2019-08-30 15:44
閱讀 1691·2019-08-29 17:22
閱讀 2763·2019-08-29 14:11
閱讀 3401·2019-08-26 13:25
閱讀 2332·2019-08-26 11:55
閱讀 1603·2019-08-26 10:37