摘要:對象的特殊性因為對象的是通過指針仔細內(nèi)存地址的,所以對象的拷貝不能像變量一般簡單的賦值,對象的賦值只是將指針的地址賦值過去而已,修改屬性值會對所有指向這個內(nèi)存地址的對象的屬性值都會被改變,見下面的例子變量賦值修改不會對造成影響對象賦值修改會
1.對象的特殊性
因為對象的是通過指針仔細內(nèi)存地址的,所以對象的拷貝不能像變量一般簡單的賦值,對象的賦值只是將指針的地址賦值過去而已,修改屬性值會對所有指向這個內(nèi)存地址的對象的屬性值都會被改變,見下面的例子:
// 變量賦值 var a = 5; var b = a; // 修改b不會對a造成影響 b=10; > a > 5 // 對象賦值 var obj = { a: "5", b: "10", c: { d: 1 } } var obj1 = obj // 修改obj1.a會對obj.a造成影響 obj1.a = 9 > obj.a > 9
所以當你使用object(array也是object的一種特殊形式)時,想復(fù)制一個object,但兩個object互不影響時,這就需要我們說的淺拷貝和深拷貝了
2.最簡單的實現(xiàn)(有局限性)// object數(shù)據(jù)中只能有基本的數(shù)據(jù)類型(String,Number,Boolean,Array,object,null,undefined),其它數(shù)據(jù)會丟失,但不會報錯 obj1 = JSON.parse(JSON.stringify(obj))3.淺拷貝
基于Object的特殊性,在對對象進行簡單的拷貝,只拷貝第一層級的屬性,這種拷貝就是淺拷貝。
function Copy(source, obj) { for (let key in obj) { source[key] = obj[key] } return source } Copy(obj1, obj) obj1.a=10 obj1.c.d=100 // 淺拷貝對第一層的屬性進行了拷貝,所以obj.a不受影響 > obj.a = 9 // 但是obj.c.d是第二層級的屬性,它受到了影響,它的值被改變了 > obj.c.d =1003.深拷貝 3.1遞歸遍歷
注意:遞歸遍歷可能爆棧,一般不會出現(xiàn)這種情況,除非對象的深度達到10000+
// 判斷數(shù)據(jù)類型的方法--更新于2019-03-28 function isType(data, type) { return Object.prototype.toString.call(data) === "[object " + type + "]" } // extendEasy實現(xiàn)深拷貝;extendSuper在深拷貝的基礎(chǔ)上實現(xiàn)多個繼承類似(source, obj1, obj2, obj3 ...) function extendSuper () { var arg = arguments for (let i = 1; i < arg.length; i++) { arg[0] = extendEasy(arg[0], arg[i]) } return arg[0] } // 實現(xiàn)深拷貝 function extendEasy (source, obj) { for (let key in obj) { // 原來使用instanceof判斷類型會存在BUG if (isType("Object",obj[key])) { source[key] = {} source[key] = extendEasy(source[key], obj[key]) } if (isType(" Array",obj[key])) { source[key] = [] source[key] = extendEasy(source[key], obj[key]) } source[key] = obj[key] } return source }3.2樹遍歷(推薦)
注意:下面代碼中Object.isType的實現(xiàn)方式-->https://segmentfault.com/a/11...
深度和廣度:pop跟push決定了深度優(yōu)先,廣度優(yōu)先請用shift和push
/* * @param target object 非必填,默認{} * @param source object 必填 * * */ function copyObject() { let root = {} const obj = arguments[arguments.length] if(!Object.isType(obj, "Object") && !Object.isType(obj, "Array")) { throw "source not Object" } if(arguments.length >= 2 && (Object.isType(arguments[0], "Object") || Object.isType(arguments[0], "Array"))) { root = arguments[0] } else { if(Object.isType(arguments[0], "Array")) { root = [] } } // 棧 const arr = [ { // key: undefined, parent: root, data: obj } ] while (arr.length) { // arr: pop跟push決定了深度優(yōu)先,廣度優(yōu)先請用shift和push const o = arr.pop() // if(o.key === undefined) { // o // } for (let item in o.data){ if (Object.isType(o.data[item], "Array")){ o.parent[item] = [] arr.push({ key: item, parent: o.parent[item], data: o.data[item] }) } else if (Object.isType(o.data[item], "Object")) { o.parent[item] = {} arr.push({ key: item, parent: o.parent[item], data: o.data[item] }) } // 如果對其它類型支持請在這里拓展 else { o.parent[item] = o.data[item] } } } return root }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/102758.html
摘要:在中可以通過添加一個參數(shù)來實現(xiàn)遞歸,調(diào)用就可以實現(xiàn)一個深拷貝。利用序列化實現(xiàn)一個深拷貝 在JavaScript中,對于Object和Array這類引用類型值,當從一個變量向另一個變量復(fù)制引用類型值時,這個值的副本其實是一個指針,兩個變量指向同一個堆對象,改變其中一個變量,另一個也會受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實例,也就是我們說的淺拷貝和深拷貝 淺拷貝(shallow...
摘要:引用數(shù)據(jù)類型是存放在堆內(nèi)存中的,變量實際上是一個存放在棧內(nèi)存的指針,這個指針指向堆內(nèi)存中的地址。棧和堆的區(qū)別其實淺拷貝和深拷貝的主要區(qū)別就是數(shù)據(jù)在內(nèi)存中的存儲類型不同。這里,對存在子對象的對象進行拷貝的時候,就是深拷貝了。 數(shù)據(jù)類型 在開始拷貝之前,我們從JavaScript的數(shù)據(jù)類型和內(nèi)存存放地址講起。數(shù)據(jù)類型分為基本數(shù)據(jù)類型 和引用數(shù)據(jù)類型 基本數(shù)據(jù)類型主要包括undefin...
摘要:說明外層數(shù)組拷貝的是實例說明元素拷貝是引用深拷貝在堆中重新分配內(nèi)存,并且把源對象所有屬性都進行新建拷貝,拷貝后的對象與原來的對象完全隔離,互不影響。中的方法可以實現(xiàn)深拷貝,源碼原理也是遞歸使用淺拷貝。 1.淺拷貝 當把數(shù)組或?qū)ο蠛唵钨x值給其他變量的時候,實際上進行的是淺拷貝,淺拷貝是拷貝引用,只是將拷貝后的引用指向同一個對象實例,彼此間的操作還會互相影響。 分為兩種情況:直接拷貝源對象...
摘要:而大多數(shù)實際項目中,我們想要的結(jié)果是兩個變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對象的屬性,而深拷貝則遞歸復(fù)制了所有層級。 為什么會用到淺拷貝和深拷貝 首先來看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
摘要:而大多數(shù)實際項目中,我們想要的結(jié)果是兩個變量初始值相同互不影響。所以就要使用到拷貝分為深淺兩種深淺拷貝的區(qū)別淺拷貝只復(fù)制一層對象的屬性,而深拷貝則遞歸復(fù)制了所有層級。 為什么會用到淺拷貝和深拷貝 首先來看一下如下代碼 let a = b = 2 a = 3 console.log(a) console.log(b) let c = d = [1,2,3] let e = f = {a:...
閱讀 3054·2023-04-26 00:40
閱讀 2391·2021-09-27 13:47
閱讀 4197·2021-09-07 10:22
閱讀 2966·2021-09-06 15:02
閱讀 3307·2021-09-04 16:45
閱讀 2484·2021-08-11 10:23
閱讀 3599·2021-07-26 23:38
閱讀 2900·2019-08-30 15:54