摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。結(jié)果如下擴(kuò)展運(yùn)算符只能對(duì)一層進(jìn)行深拷貝如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝那么我們可以看到和展開(kāi)原算符對(duì)于深淺拷貝的結(jié)果是一樣。
JS中數(shù)據(jù)類型
基本數(shù)據(jù)類型: undefined、null、Boolean、Number、String和Symbol(ES6)
引用數(shù)據(jù)類型: Object(Array, Date, RegExp, Function)
深淺拷貝深淺拷貝只是針對(duì)引用類型的,因?yàn)橐妙愋褪谴娣旁诙褍?nèi)存中,在棧地址有一個(gè)或者多個(gè)地址來(lái)指向推內(nèi)存的某一數(shù)據(jù)
淺拷貝:被復(fù)制對(duì)象的所有變量都含有與原來(lái)的對(duì)象相同的值,而所有的對(duì)其他對(duì)象的引用仍然指向原來(lái)的對(duì)象。
淺拷貝僅僅復(fù)制所考慮的對(duì)象,而不復(fù)制它所引用的對(duì)象,如果你修改了“副本”的值,那么原來(lái)的對(duì)象也會(huì)被修改
深拷貝:深拷貝是一個(gè)整個(gè)獨(dú)立的對(duì)象拷貝,深拷貝會(huì)拷貝所有的屬性,并拷貝屬性指向的動(dòng)態(tài)分配的內(nèi)存。當(dāng)對(duì)象和它所引用的對(duì)象一起拷貝時(shí)即發(fā)生深拷貝。深拷貝相比于淺拷貝速度較慢并且花銷較大。
深拷貝把要復(fù)制的對(duì)象所引用的對(duì)象都復(fù)制了一遍。如果你修改了“副本”的值,那么原來(lái)的對(duì)象不會(huì)被修改,兩者是相互獨(dú)立的。
用例子看深淺拷貝 賦值實(shí)現(xiàn)淺拷貝let arr = [22, 44, 66, 88]; let co = arr; co[0] = 11; console.log(arr, co);
結(jié)果如圖:
我們本來(lái)想把 arr 賦值給 co ,當(dāng)我們修改co數(shù)組中第一個(gè)元素時(shí),卻發(fā)現(xiàn)了原始數(shù)組arr發(fā)生了改變
很顯然,這就是一個(gè)淺拷貝的例子
原理:JSON實(shí)現(xiàn)深拷貝
對(duì)于引用類型,賦值操作符只是把存放在棧內(nèi)容中的指針賦值給另外一個(gè)變量。
所以在賦值完成后,在棧內(nèi)存就有兩個(gè)指針指向堆內(nèi)存同一個(gè)數(shù)據(jù)。
也就可以說(shuō)兩個(gè)變量在共用著同一個(gè)數(shù)據(jù),這就是淺拷貝。
let arr = [22, 44, 66, 88]; let jso = JSON.parse(JSON.stringify(arr)); jso[0] = 11; console.log(arr, jso);
結(jié)果如圖:
對(duì)比之前賦值的結(jié)果,我們發(fā)現(xiàn)原來(lái)的數(shù)組arr并沒(méi)有被改變,可以說(shuō)兩者是相互獨(dú)立的
很顯然,這就是一個(gè)深拷貝的例子
原理:
JSON.parse() 方法用于將一個(gè) JSON 字符串轉(zhuǎn)換為對(duì)象。
JSON.stringify() 方法用于將 JavaScript 值(通常為對(duì)象或數(shù)組)轉(zhuǎn)換為 JSON 字符串。
在JSON.stringify()完成后,對(duì)象就轉(zhuǎn)為了字符串,也就可以說(shuō)實(shí)實(shí)在在的復(fù)制了一個(gè)值,不存在引用之說(shuō)。
再利用JSON.parse()轉(zhuǎn)為對(duì)象,這樣達(dá)到深拷貝的目的
JSON實(shí)現(xiàn)深拷貝的缺陷:
來(lái)看下面例子:
let obj = { nul: null, und: undefined, sym: Symbol("sym"), str: "str", bol: true, num: 45, arr: [1, 4], reg: /[0-9]/, dat: new Date(), fun: function() {}, } console.log(JSON.parse(JSON.stringify(obj)))
結(jié)果如圖:
我們可以發(fā)現(xiàn)有些屬性被忽略了:
undefined
symbol
function
可以看得出來(lái)JSON實(shí)現(xiàn)深拷貝也有不足之處
ES6新特性實(shí)現(xiàn)拷貝 Object.assign()Object.assign方法用于對(duì)象的合并,將源對(duì)象(source)的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象(target)。
Object.assign(target, ...sources)
target目標(biāo)對(duì)象。 sources源對(duì)象。 返回的是目標(biāo)對(duì)象
let obj = { a: { a1: "a1" }, b: "b" } let ass = Object.assign({}, obj); ass.a.a1 = "aaa"; aconsole.log(obj, ass);
我們看下結(jié)果:
我們可以看到a1的值被改變,而b的值沒(méi)有被改變,說(shuō)明了:
Obejct.assign()只能對(duì)一層進(jìn)行深拷貝展開(kāi)運(yùn)算符(...)
如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝
對(duì)象的擴(kuò)展運(yùn)算符(...)用于取出參數(shù)對(duì)象的所有可遍歷屬性,拷貝到當(dāng)前對(duì)象之中。
let obj = { a: { a1: "a1" }, b: "b" } let ass = {...obj}; ass.a.a1 = "aaa"; ass.b = "bbb"
結(jié)果如下:
擴(kuò)展運(yùn)算符只能對(duì)一層進(jìn)行深拷貝
如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝
那么我們可以看到Object.assign()和展開(kāi)原算符對(duì)于深淺拷貝的結(jié)果是一樣。
如果拷貝的層數(shù)超過(guò)了一層的話,那么就會(huì)進(jìn)行淺拷貝
所以要慎用這兩個(gè)來(lái)進(jìn)行拷貝!!!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/100714.html
摘要:動(dòng)手實(shí)現(xiàn)深拷貝利遞歸來(lái)實(shí)現(xiàn)對(duì)對(duì)象或數(shù)組的深拷貝。遞歸思路對(duì)屬性中所有引用類型的值進(jìn)行遍歷,直到是基本類型值為止。深拷貝只對(duì)對(duì)象自有屬性進(jìn)行拷貝測(cè)試數(shù)據(jù)拷貝方式其實(shí)也是一種繼承的方式,當(dāng)然繼承還是有其他方法的感謝支持 深淺拷貝 基本類型 & 引用類型 ECMAScript中的數(shù)據(jù)類型可分為兩種: 基本類型:undefined,null,Boolean,String,Number,Symb...
摘要:總結(jié)綜上所述,數(shù)組的深拷貝比較簡(jiǎn)單,方法沒(méi)有什么爭(zhēng)議,對(duì)象的深拷貝,比較好的方法是用的方法實(shí)現(xiàn),或者遞歸實(shí)現(xiàn),比較簡(jiǎn)單的深復(fù)制可以使用實(shí)現(xiàn)參考資料知乎中的深拷貝和淺拷貝深入剖析的深復(fù)制 深淺復(fù)制對(duì)比 因?yàn)镴avaScript存儲(chǔ)對(duì)象都是存地址的,所以淺復(fù)制會(huì)導(dǎo)致 obj 和obj1 指向同一塊內(nèi)存地址。我的理解是,這有點(diǎn)類似數(shù)據(jù)雙向綁定,改變了其中一方的內(nèi)容,都是在原來(lái)的內(nèi)存基礎(chǔ)上做...
摘要:圖數(shù)據(jù)類型圖引用類型深淺拷貝問(wèn)題不知道什么是深拷貝和淺拷貝的請(qǐng)先去并在調(diào)試臺(tái)自己操作一下,這篇文章只會(huì)說(shuō)明為何中會(huì)有這種問(wèn)題。所以有的時(shí)候我們?yōu)榱吮苊鉁\拷貝,會(huì)用一些方式實(shí)現(xiàn)深拷貝。 首先要了解的js基礎(chǔ) 基本數(shù)據(jù)類型:Object、undefined、null、Boolean、Number、String、Symbol (ES6新加) Object包括: Array 、Date 、R...
摘要:基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì),這類引用類型數(shù)據(jù)。它會(huì)拋棄對(duì)象的。另外,查資料過(guò)程中還看到這么一個(gè)詞結(jié)構(gòu)化克隆算法還有這一篇資料也有參考,也寫得比較詳細(xì)了的深淺拷貝 基本數(shù)據(jù)類型的復(fù)制很簡(jiǎn)單,就是賦值操作,所以深淺拷貝也是針對(duì)Object,Array這類引用類型數(shù)據(jù)。 淺拷貝對(duì)于字符串來(lái)說(shuō),是值的復(fù)制,而對(duì)于對(duì)象來(lái)說(shuō)則是對(duì)對(duì)象地址的復(fù)制;而深拷貝的話,它不...
閱讀 2123·2021-11-23 10:06
閱讀 3488·2021-11-11 16:54
閱讀 3352·2019-08-29 17:31
閱讀 3576·2019-08-29 17:05
閱讀 2175·2019-08-26 13:36
閱讀 2165·2019-08-26 12:17
閱讀 536·2019-08-26 12:12
閱讀 1681·2019-08-26 10:19