摘要:深拷貝淺拷貝淺拷貝淺拷貝只是復(fù)制了內(nèi)存地址,如果原地址中的對(duì)象改變了,淺拷貝出來(lái)的對(duì)象也會(huì)相應(yīng)改變。也就是深拷貝之后,不管這個(gè)對(duì)象原來(lái)的構(gòu)造函數(shù)是什么,在深拷貝之后都會(huì)變成。
JavaScript深拷貝、淺拷貝
淺拷貝:淺拷貝只是復(fù)制了內(nèi)存地址,如果原地址中的對(duì)象改變了,淺拷貝出來(lái)的對(duì)象也會(huì)相應(yīng)改變。淺拷貝數(shù)組(只拷貝第一級(jí)數(shù)組):
深拷貝:開(kāi)辟了一塊新的內(nèi)存存放地址和地址指向的對(duì)象,原地址的任何對(duì)象改變了,深拷貝出來(lái)的對(duì)象不變。
var arr = [1,2,3,4]; function copy(arg){ var newArr = []; for(var i = 0; i < arr.length; i++) { newArr.push(arr[i]); } return newArr; } var newArry = copy(arr); console.log(newArry); newArry[0] = 10; console.log(newArry); // [10,2,3,4] console.log(arr) // [1,2,3,4]
var arr = [1,2,3,4] var copyArr = arr.slice(); copyArr[0] = 10; console.log(copyArr); // [10,2,3,4] console.log(arr); // [1,2,3,4]
slice(start,end),slice()方法返回一個(gè)數(shù)組中復(fù)制出來(lái)的元素組成新數(shù)組,start指起始元素下標(biāo),end指終止元素下標(biāo)
當(dāng)slice()不帶任何參數(shù)時(shí),默認(rèn)返回一個(gè)和原數(shù)組一樣的新數(shù)組
var arr = [1,2,3,4] var copyArr = arr.concat(); copyArr[0] = 10; console.log(copyArr); // [10,2,3,4] console.log(arr); // [1,2,3,4]
array.concat(array1,array2,.......,arrayN),concat()方法用于連接兩個(gè)或多個(gè)數(shù)組(不會(huì)改變?cè)瓟?shù)組,返回被連接數(shù)組的副本)
var arr = [ {number:1}, {number:2}, {number:3} ] var copyArr = arr.slice(); copyArr[0].number = 10; console.log(copyArr); // [{number: 100}, { number: 2 },{ number: 3 }] console.log(arr); // [{number: 100}, { number: 2 }, { number: 3 }]淺拷貝對(duì)象(如果對(duì)象中的值不為數(shù)組或?qū)ο螅?/b>
var obj = { name: "張三", job: "學(xué)生" } function copy (arg) { let newobj = {} for(let item in arg) { newobj[item] = arg[item]; } return newobj; } var copyobj = copy(obj) copyobj.name = "李四" console.log(copyobj) // {name: "李四", job:: "學(xué)生"} console.log(obj) // {name: "張三", job:: "學(xué)生"}
var obj = { name: "張三", job: "學(xué)生" } var copyobj = Object.assign({},obj) copyobj.name = "李四" console.log(copyobj) // {name: "李四", job:: "學(xué)生"} console.log(obj) // {name: "張三", job:: "學(xué)生"}
Object.assign:用于對(duì)象的合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target),并返回合并后的target
用法: Object.assign(target, source1, source2); 所以 copyObj = Object.assign({}, obj); 這段代碼將會(huì)把obj中的一級(jí)屬性都拷貝到 {}中,然后將其返回賦給copyObj
3.ES6擴(kuò)展運(yùn)算符
var obj = { name: "張三", job: "學(xué)生" } var copyobj = {...obj} copyobj.name = "李四" console.log(copyobj) console.log(obj)
擴(kuò)展運(yùn)算符(...)用于取出參數(shù)對(duì)象的所有可遍歷屬性,拷貝到當(dāng)前對(duì)象之中深拷貝
JSON.stringify()和JSON.parse()
用JSON.stringify把對(duì)象轉(zhuǎn)成字符串,再用JSON.parse把字符串轉(zhuǎn)成新的對(duì)象。
但是這種方法也有不少壞處,譬如它會(huì)拋棄對(duì)象的constructor。也就是深拷貝之后,不管這個(gè)對(duì)象原來(lái)的構(gòu)造函數(shù)是什么,在深拷貝之后都會(huì)變成Object。
這種方法能正確處理的對(duì)象只有 Number, String, Boolean, Array, 扁平對(duì)象,即那些能夠被 json 直接表示的數(shù)據(jù)結(jié)構(gòu)。RegExp對(duì)象是無(wú)法通過(guò)這種方式深拷貝。
也就是說(shuō),只有可以轉(zhuǎn)成JSON格式的對(duì)象才可以這樣用,像function、undefined、symbol、循環(huán)引用的對(duì)象沒(méi)辦法轉(zhuǎn)成JSON。
var obj1 = { fun: function(){ console.log(123) } }; var obj2 = JSON.parse(JSON.stringify(obj1)); console.log(typeof obj1.fun); // "function" console.log(typeof obj2.fun); // "undefined" <-- 沒(méi)復(fù)制
function deepClone(obj) { let objClone = Array.isArray(obj) ? [] : {}; if(obj && typeof obj === "object") { for(key in obj) { if(obj.hasOwnProperty(key)) { if(obj[key] && typeof obj[key] === "object") { objClone[key] = deepClone(obj[key]); } else { objClone[key] = obj[key]; } } } } return objClone }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/101413.html
摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 上一篇 JavaScript中的繼承 前言 文章開(kāi)始之前,讓我們先思考一下這幾個(gè)問(wèn)題: 為什么會(huì)有淺拷貝與深拷貝 什么是淺拷貝與深拷貝 如何實(shí)現(xiàn)淺拷貝與深拷貝 好了,問(wèn)題出來(lái)了,那么下面就讓我們帶著這幾個(gè)問(wèn)題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處...
摘要:所以,深拷貝是對(duì)對(duì)象以及對(duì)象的所有子對(duì)象進(jìn)行拷貝實(shí)現(xiàn)方式就是遞歸調(diào)用淺拷貝對(duì)于深拷貝的對(duì)象,改變?cè)磳?duì)象不會(huì)對(duì)得到的對(duì)象有影響。 為什么會(huì)有淺拷貝與深拷貝什么是淺拷貝與深拷貝如何實(shí)現(xiàn)淺拷貝與深拷貝好了,問(wèn)題出來(lái)了,那么下面就讓我們帶著這幾個(gè)問(wèn)題去探究一下吧! 如果文章中有出現(xiàn)紕漏、錯(cuò)誤之處,還請(qǐng)看到的小伙伴多多指教,先行謝過(guò) 以下↓ 數(shù)據(jù)類型在開(kāi)始了解 淺拷貝 與 深拷貝 之前,讓我們先...
摘要:在中可以通過(guò)添加一個(gè)參數(shù)來(lái)實(shí)現(xiàn)遞歸,調(diào)用就可以實(shí)現(xiàn)一個(gè)深拷貝。利用序列化實(shí)現(xiàn)一個(gè)深拷貝 在JavaScript中,對(duì)于Object和Array這類引用類型值,當(dāng)從一個(gè)變量向另一個(gè)變量復(fù)制引用類型值時(shí),這個(gè)值的副本其實(shí)是一個(gè)指針,兩個(gè)變量指向同一個(gè)堆對(duì)象,改變其中一個(gè)變量,另一個(gè)也會(huì)受到影響。 這種拷貝分為兩種情況:拷貝引用和拷貝實(shí)例,也就是我們說(shuō)的淺拷貝和深拷貝 淺拷貝(shallow...
摘要:對(duì)象的淺拷貝淺拷貝是對(duì)象共用一個(gè)內(nèi)存地址,對(duì)象的變化相互影響。這是特別值得注意的地方。和能正確處理的對(duì)象只有等能夠被表示的數(shù)據(jù)結(jié)構(gòu),因此函數(shù)這種不能被表示的類型將不能被正確處理。 對(duì)象的淺拷貝: 淺拷貝是對(duì)象共用一個(gè)內(nèi)存地址,對(duì)象的變化相互影響。比如常見(jiàn)的賦值引用就是淺拷貝: let srcObj = {name: lilei, age: 20}; let copyObj = srcO...
摘要:原文地址淺拷貝和深拷貝只針對(duì)像這樣的復(fù)雜對(duì)象的簡(jiǎn)單來(lái)說(shuō),淺拷貝只拷貝一層對(duì)象的屬性,而深拷貝則遞歸拷貝了所有層級(jí)。淺拷貝通過(guò)來(lái)實(shí)現(xiàn)淺拷貝。 原文地址:http://www.silenceboy.com/201... 淺拷貝和深拷貝只針對(duì)像Object, Array這樣的復(fù)雜對(duì)象的.簡(jiǎn)單來(lái)說(shuō),淺拷貝只拷貝一層對(duì)象的屬性,而深拷貝則遞歸拷貝了所有層級(jí)。 淺拷貝 通過(guò) Object.ass...
摘要:它將返回目標(biāo)對(duì)象。有些文章說(shuō)是深拷貝,其實(shí)這是不正確的。深拷貝相比于淺拷貝速度較慢并且花銷較大??截惽昂髢蓚€(gè)對(duì)象互不影響。使用深拷貝的場(chǎng)景完全改變變量之后對(duì)沒(méi)有任何影響,這就是深拷貝的魔力。 一、賦值(Copy) 賦值是將某一數(shù)值或?qū)ο筚x給某個(gè)變量的過(guò)程,分為: 1、基本數(shù)據(jù)類型:賦值,賦值之后兩個(gè)變量互不影響 2、引用數(shù)據(jù)類型:賦址,兩個(gè)變量具有相同的引用,指向同一個(gè)對(duì)象,相互之間有...
閱讀 1532·2021-11-18 10:02
閱讀 1690·2021-09-04 16:40
閱讀 3184·2021-09-01 10:48
閱讀 884·2019-08-30 15:55
閱讀 1861·2019-08-30 15:55
閱讀 1382·2019-08-30 13:05
閱讀 3027·2019-08-30 12:52
閱讀 1634·2019-08-30 11:24