摘要:簡單來說,就是把復制過程中的源對象都記錄下來,以及對應的拷貝對象,碰到屬性值是之前復制過的對象的情況,的屬性值是,就把對應的拷貝對象給它,,而不進行遞歸深拷貝。例如的屬性值是的地址,那么拷貝過程中,的屬性值就是的地址。
基礎類型與引用(地址) 例子一
let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123 } let obj1 = obj console.log(obj1) // { c: "l am an obj", d: 123 } obj1.c = "l am an obj1" console.log(obj) // { c: "l am an obj1", d: 123 } console.log(obj1) // { c: "l am an obj1", d: 123 }
變量obj存的是地址address01,執行let obj1 = obj后,變量obj1存的還是address01。就好像主臥室(obj),或大房間(obj1),都指的是房間號為address01的房間。所以,你說“換掉大房間的床”,obj1.c = "l am an obj1",等同于“換掉主臥室的床”,因為都是“換掉房間號為address01的房間里的床”。
例子二let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123 } let obj1 = {} obj1.c = obj.c obj1.d = obj.d console.log(obj1) // { c: "l am an obj", d: 123 } obj1.c = "l am an obj1" console.log(obj) // { c: "l am an obj", d: 123 } console.log(obj1) // { c: "l am an obj1", d: 123 }
變量obj存的是地址address01,執行let obj1 = {}后,變量obj1得到了一個新的地址address02。現在不僅有房間號為address01的主臥室(obj),還有房間號為address02的次臥(obj1),在那里你可以布置你自己的新房間。你可以先說“要一張和主臥一樣的床”,obj1.c = obj.c,再說“還要一臺和主臥一樣的燈”,obj1.d = obj.d,最后你又覺得床不舒服,“換了張床”,obj1.c = "l am an obj1",但這些都不會影響主臥的床obj.c。
例子三let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123, e: [1, 3, 5] } let obj1 = {} obj1.c = obj.c obj1.d = obj.d obj1.e = obj.e console.log(obj1) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] } obj1.c = "l am an obj1" obj1.e[0] = 2 console.log(obj) // { c: "l am an obj", d: 123, e: [ 2, 3, 5 ] } console.log(obj1) // { c: "l am an obj1", d: 123, e: [ 2, 3, 5 ] }
主臥里面還可以有衛生間obj.e的呢,obj.e存的也是地址adress03,只要是對象或數組都存的是地址。這時obj1.e = obj.e,存的就是主臥的衛生間的房間號address03。目前只有一個衛生間,你知道衛生間的地址adress03,保存在obj1.e中,然后你就知道如何“把衛生間的熱水器換掉”,obj1.e[0] = 2。
例子四let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123, e: [1, 3, 5] } let obj1 = {} obj1.c = obj.c obj1.d = obj.d obj1.e = obj.e console.log(obj1) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] } obj1.c = "l am an obj1" obj1.e = "l am not an arr" console.log(obj) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] } console.log(obj1) // { c: "l am an obj1", d: 123, e: "l am not an arr" }
后來你覺得知道主臥的衛生間的地址adress03有什么用,有那閑工夫還不如用來放個柜子,故obj1.e = "l am not an arr",這樣做以后,沒有了衛生間的地址,你就不能在主臥的衛生間里搗亂了。
例子五let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123, e: [1, 3, 5] } let obj1 = {} obj1.c = obj.c obj1.d = obj.d obj1.e = [] for (let i = 0; i < obj.e.length; i++) { obj1.e[i] = obj.e[i] } console.log(obj1) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] } obj1.c = "l am an obj1" obj1.e[0] = 2 console.log(obj) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] } console.log(obj1) // { c: "l am an obj1", d: 123, e: [ 2, 3, 5 ] }
其實你還是想要個獨立衛生間的,obj1.e = [],這樣你得到了房間號為adress04的房間,然后你按照主臥衛生間的樣子來改造這個房間for (let i = 0; i < obj.e.length; i++) { obj1.e[i] = obj.e[i] }。這時候有兩個獨立的衛生間了,房間號分別是adress04和adress03,盡管布局裝飾一樣,但還是兩個房間,賓館里的房間還都一樣呢,但它們有不同的房間號,實際上是相互獨立的房間。你換adress04房間的熱水器,obj1.e[0] = 2,并不會影響房間adress03房間。
抽象例子五的復制過程即深拷貝
let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123, e: [1, 3, 5] } function deepCopy(val) { if (!val || typeof val !== "object") { return val } let copy = Array.isArray(val) ? [] : {} for (key in val) { if (val.hasOwnProperty(key)) { if (val[key] && typeof val[key] === "object") { copy[key] = deepCopy(val[key]) } else { copy[key] = val[key] } } } return copy } let obj1 = deepCopy(obj) obj1.c = "l am an obj1" obj1.e[0] = 2 console.log(obj) // { c: "l am an obj", d: 123, e: [ 1, 3, 5 ] } console.log(obj1) // { c: "l am an obj1", d: 123, e: [ 2, 3, 5 ] }例子六
let a = "l am a string" let b = 6 let obj = { c: "l am an obj", d: 123, e: {} } obj.e.parent = obj let keyValArr = [] let copyArr = [] function deepCopy(val) { if (!val || typeof val !== "object") { return val } let copy = Array.isArray(val) ? [] : {} let index = keyValArr.indexOf(val) if (index === -1) { keyValArr.push(val) copyArr.push(copy) } else { return copyArr[index] } for (key in val) { if (val.hasOwnProperty(key)) { if (val[key] && typeof val[key] === "object") { copy[key] = deepCopy(val[key]) } else { copy[key] = val[key] } } } return copy } let obj1 = deepCopy(obj) obj1.e.parent.c = "l am an obj1" console.log(obj) // { c: "l am an obj", d: 123, e: { parent: [Circular] } } console.log(obj1) // { c: "l am an obj1", d: 123, e: { parent: [Circular] } }
總有人想尋根問祖,obj.e.parent = obj,如此形成了環,之前的代碼就要重新調整。簡單來說,就是把復制過程中的源對象[obj, obj.e]都記錄下來,以及對應的拷貝對象[copy, copy.e],碰到屬性值是之前復制過的對象的情況,obj.e.parent的屬性值是obj,就把對應的拷貝對象給它,copy.e.parent = copy,而不進行遞歸深拷貝。
從地址的角度來說,復制過程中,把地址都記錄下來,用valArr記錄源對象的地址[address01, address03],用copyArr記錄拷貝對象的地址[address02, address04],當碰到需要拷貝的是之前記錄過源對象的地址時,就把對應的拷貝對象的地址返回。例如obj.e.parent的屬性值是obj的地址,那么拷貝過程中,obj1.e.parent的屬性值就是obj1的地址。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89462.html
摘要:原文地址基礎心法深淺拷貝歡迎。上面的代碼是最簡單的利用賦值操作符實現了一個淺拷貝,可以很清楚的看到,隨著和改變,和也隨著發生了變化。展開運算符結論實現的是對象第一層的深拷貝。 原文地址:JavaScript基礎心法——深淺拷貝 歡迎star。 如果有錯誤的地方歡迎指正。 淺拷貝和深拷貝都是對于JS中的引用類型而言的,淺拷貝就只是復制對象的引用,如果拷貝后的對象發生變化,原對象也會發生...
摘要:所以,深拷貝是對對象以及對象的所有子對象進行拷貝實現方式就是遞歸調用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 上一篇 JavaScript中的繼承 前言 文章開始之前,讓我們先思考一下這幾個問題: 為什么會有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實現淺拷貝與深拷貝 好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現紕漏、錯誤之處...
摘要:所以,深拷貝是對對象以及對象的所有子對象進行拷貝實現方式就是遞歸調用淺拷貝對于深拷貝的對象,改變源對象不會對得到的對象有影響。 為什么會有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實現淺拷貝與深拷貝好了,問題出來了,那么下面就讓我們帶著這幾個問題去探究一下吧! 如果文章中有出現紕漏、錯誤之處,還請看到的小伙伴多多指教,先行謝過 以下↓ 數據類型在開始了解 淺拷貝 與 深拷貝 之前,讓我們先...
摘要:引用和值拷貝微信公眾號開發企業級產品全棧開發速成周末班首期班號正式開班,歡迎搶座作者黎躍春追時間的人簡介是推出的一個天挑戰。深拷貝與淺拷貝對比創建對象黎躍春淺拷貝深拷貝將對象轉換成字符串,打印時效果清晰。 Day14 - JavaScript 引用和值拷貝 (Node+Vue+微信公眾號開發)企業級產品全棧開發速成周末班首期班(10.28號正式開班,歡迎搶座) 作者:?黎躍春-追時間的...
摘要:棧內存與堆內存淺拷貝與深拷貝,可以說是前端程序員的內功,要知其然,知其所以然。棧內存與堆內存中的變量分為基本類型和引用類型。 showImg(https://segmentfault.com/img/bVbuvnj?w=900&h=250); 前言 想寫好前端,先練好內功。 棧內存與堆內存 、淺拷貝與深拷貝,可以說是前端程序員的內功,要知其然,知其所以然。 筆者寫的 JavaScrip...
摘要:在中可以通過添加一個參數來實現遞歸,調用就可以實現一個深拷貝。利用序列化實現一個深拷貝 在JavaScript中,對于Object和Array這類引用類型值,當從一個變量向另一個變量復制引用類型值時,這個值的副本其實是一個指針,兩個變量指向同一個堆對象,改變其中一個變量,另一個也會受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實例,也就是我們說的淺拷貝和深拷貝 淺拷貝(shallow...
閱讀 3014·2021-11-16 11:42
閱讀 3653·2021-09-08 09:36
閱讀 950·2019-08-30 12:52
閱讀 2481·2019-08-29 14:12
閱讀 769·2019-08-29 13:53
閱讀 3583·2019-08-29 12:16
閱讀 644·2019-08-29 12:12
閱讀 2469·2019-08-29 11:16