摘要:前言里面淺拷貝和深拷貝是非常關鍵的知識點,今天就來通過本文清楚的了解深淺拷貝以及該如何實現這兩種拷貝方式。對象的拷貝又分為淺拷貝和深拷貝。印證了上述所說的對于所有的基本類型,簡單的賦值已經是實現了深拷貝。
前言
JavaScript里面淺拷貝和深拷貝是非常關鍵的知識點,今天就來通過本文清楚的了解深淺拷貝以及該如何實現這兩種拷貝方式。
深淺拷貝的區別拷貝:其實就是一個對象復制給另外一整個對象,讓對象相互不影響。對象的拷貝又分為淺拷貝和深拷貝。
對象的淺拷貝(只拷貝一層),所謂的淺拷貝,只是拷貝了基本類型的數據,對于引用的類型數據,復制后也是會發生引用,這種拷貝就叫做淺拷貝。
對象的深拷貝(拷貝多層),要求要復制一個復雜的對象,這就可以利用遞歸的思想來實現,省性能又不會發生引用,它不僅將原對象的各個屬性逐個復制出去,而且將原對象各個屬性所包含的對象也依次采用深復制的方法遞歸復制到新對象上。
淺拷貝和深拷貝只針對object這樣的復雜的對象而深拷貝,因為對于所有的基本類型,簡單的賦值已經是實現了深拷貝。
例子1.首先來讓我們思考一下以下的 a 應該是多少?
顯而易見,a 是1。印證了上述所說的對于所有的基本類型,簡單的賦值已經是實現了深拷貝。我們可以簡單地理解,這種b變了不影響a的就叫做深拷貝。
例子2.那么在這種情況下,a.name 又是多少呢?
*以下44為假設,下同。
很明顯,a.name 是"b"。同樣我們可以簡單地理解,這種b變了影響a的就叫做淺拷貝。
在例子2中,為什么 b 改變了會影響 a 呢?因為我們僅僅是把堆里所記錄的地址44復制給了 b ,所以在后來我們對 b.name 修改時,會對44里記錄的 name 直接修改,當 a 再去引用的時候已經是被修改過的44了。
我們想要在修改時候兩者互不影響,應該是要像上圖一樣,創建一個新地址55,里面所包含的內容和地址44一樣,這樣在修改時才會互不影響。同樣如果引用里還有引用,也要做到內容一樣地址不一樣,只有兩者引用互無關聯才能做到互不影響,才能實現了深拷貝。
在了解了深淺拷貝的區別之后,我們想要實現深淺拷貝的話該怎么辦呢?
淺拷貝
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()我們可以很簡單的實現了深拷貝,但是值得注意的是,JSON.parse() 和 JSON.stringify() 能正確處理的對象只有 Number、String、Array 等能夠被 json 表示的數據結構,因此函數、Date等這種不能被 json 表示的類型將不能被正確處理。
2.判斷類型 + 遞歸拷貝(不可能復制__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 }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/106502.html
摘要:淺拷貝深拷貝淺拷貝的問題如果父對象的屬性等于數組或另一個對象,那么實際上,子對象獲得的只是一個內存地址,而不是真正拷貝,因此存在父對象被篡改的可能。 淺拷貝: function extendCopy(p) { var c = {}; for (var i in p) { c[i] = p[i]; } return c; } 深拷貝: function deepCopy(p...
摘要:判斷是深拷貝對象還是數組如果要拷貝的對象的屬性依然是個復合類型,遞歸運用遞歸,當要拷貝的對象或者數組的屬性依然是個對象或者數組時,遞歸調用。遍歷對象聊完了深拷貝和淺拷貝,接下來說一下遍歷。 在js這門語言中,數據存放在堆中,而數據的引用的存放在棧中。 淺拷貝 我們說的淺拷貝,指的是,引用地址的拷貝,棧中兩塊不同的引用地址都指向了堆中同樣一塊區域。所以,我們通過一個地址修改了堆中的數據,...
摘要:定義淺復制如果復制引用,復制后的引用都是指向同一個對象的實例,彼此之間的操作會互相影響。淺復制數組淺復制利用數組方法和返回新數組特性,進行復制。深復制對象深復制利用對象的和方法。 定義 淺復制 如果復制引用,復制后的引用都是指向同一個對象的實例,彼此之間的操作會互相影響。 深復制 深復制不是簡單的復制引用,而是在堆中重新分配內存,并且把源對象實例的所有屬性都進行新建復制,以保證深復制的...
摘要:所以,深拷貝是對對象以及對象的所有子對象進行拷貝實現方式就是遞歸調用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 上一篇 JavaScript中的繼承 前言 文章開始之前,讓我們先思考一下這幾個問題: 為什么會有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實現淺拷貝與深拷貝 好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現紕漏、錯誤之處...
閱讀 3973·2021-11-16 11:44
閱讀 5209·2021-10-09 09:54
閱讀 2034·2019-08-30 15:44
閱讀 1683·2019-08-29 17:22
閱讀 2756·2019-08-29 14:11
閱讀 3393·2019-08-26 13:25
閱讀 2328·2019-08-26 11:55
閱讀 1600·2019-08-26 10:37