摘要:關(guān)于深拷貝和淺拷貝從原理看淺拷貝拷貝一層,對(duì)象級(jí)別的則拷貝引用深拷貝拷貝多層,每個(gè)層級(jí)的屬性都會(huì)拷貝從現(xiàn)象看復(fù)制了,被修改后,隨變化而變化淺拷貝不變深拷貝深拷貝針對(duì)的復(fù)雜的類型數(shù)據(jù)如直接賦值的單層拷貝,如,雖然不受的影響,但是這也不算做
關(guān)于深拷貝和淺拷貝
從原理看:
淺拷貝:拷貝一層,對(duì)象級(jí)別的則拷貝引用
深拷貝:拷貝多層,每個(gè)層級(jí)的屬性都會(huì)拷貝
從現(xiàn)象看:
A復(fù)制了B,B被修改后,
A隨B變化而變化->淺拷貝
A不變->深拷貝
深拷貝針對(duì)的s復(fù)雜的object類型數(shù)據(jù)
∴如直接賦值的單層拷貝,如b=a,b雖然不受a的影響,但是這也不算做深拷貝
現(xiàn)象只是作為方便理解的一個(gè)參考,真正的判斷標(biāo)準(zhǔn)還是要從原理上看
數(shù)據(jù)類型分為:
基本數(shù)據(jù)類型(7種):namevalue都存儲(chǔ)在棧內(nèi)存中
引用數(shù)據(jù)類型:name->棧內(nèi)存,值->堆內(nèi)存,棧內(nèi)存會(huì)提供一個(gè)引用的地址指向堆內(nèi)存的值
當(dāng)b=a進(jìn)行拷貝時(shí),b復(fù)制的是a的引用地址,并不是堆里面的值,所以這便造成了當(dāng)a發(fā)生改變,b也會(huì)隨之改變的淺拷貝
實(shí)現(xiàn)淺拷貝的方法:
一、 直接復(fù)制
//基本數(shù)據(jù)類型 var arr = [1, 2, 3, "4"]; var arr2 = arr; arr2[1] = "test"; console.log(arr); // [1, "test", 3, "4"] console.log(arr2); // [1, "test", 3, "4"] //改變其中一個(gè)對(duì)象的屬性值,兩個(gè)對(duì)象都發(fā)生了改變 //obj和obj2兩個(gè)變量都指向同一個(gè)指針,賦值時(shí)只是復(fù)制了指針地址,它們指向同一個(gè)引用,∴當(dāng)我們改變其中一個(gè)的值,另一個(gè)變量的值也會(huì)隨之改變 ---------- //對(duì)象級(jí) function Clone(obj1){ var obj2 ={}; for(var i in obj1) { obj2[i]=obj1[i]; } return obj2; }
淺拷貝只是拷貝了一層,除了對(duì)象是拷貝引用類型,其他的都是直接將值傳遞,有自己的內(nèi)存空間
二、ES6中的Object.assign()方法
該方法可以把任意多個(gè)的源對(duì)象自身的可枚舉屬性拷貝給對(duì)象,然后返回目標(biāo)對(duì)象
Object.assign(目標(biāo)對(duì)象,任意多個(gè)源對(duì)象)
var obj1 = { a: "hello", b: { a: "hello", b: 21} }; var cloneObj1= Object.assign({}, obj1); cloneObj1.a = "changed"; cloneObj1.b.a = "changed"; console.log(obj1.a); //hello console.log(obj.b.a); // "changed"
如果對(duì)象只有一層,這個(gè)函數(shù)可以作為深拷貝的方法
var obj2 = { a: 10, b: 20, c: 30 }; var cloneObj2 = Object.assign({}, obj2); cloneObj2.b = 100; console.log(obj2); // { a: 10, b: 20, c: 30 } <-- 沒(méi)有改變,實(shí)現(xiàn)了深拷貝 console.log(cloneObj2); // { a: 10, b: 100, c: 30 }
若想實(shí)現(xiàn)深拷貝,就需要在堆中開(kāi)辟一個(gè)內(nèi)存,用來(lái)存放b的值。
方法一、手動(dòng)復(fù)制
將A對(duì)象項(xiàng)的屬性逐個(gè)負(fù)責(zé)給另一個(gè)對(duì)象的屬性
var ob1 = {a:1,b:2,c:3}; var ob2 = {a:ob1.a,b:ob1.b,c:ob1.c}; ob1.a = 0; ob2.b = 0; console.log(ob1);//023 console.log(ob2);//103
這樣很麻煩,且本質(zhì)上不能算作深拷貝,當(dāng)ob1內(nèi)嵌套對(duì)象c時(shí),ob1和ob2將共享c,當(dāng)改變c的屬性時(shí),ob1ob2將都發(fā)生改變
方法二、將對(duì)象通過(guò)JSON方法轉(zhuǎn)成字符串再轉(zhuǎn)回來(lái)
可以實(shí)現(xiàn)真正的深拷貝,但是只能用于可以轉(zhuǎn)成JSON格式的對(duì)象,function無(wú)法轉(zhuǎn)換成JSON,就不能夠使用
∴此方法會(huì)舍棄對(duì)象的構(gòu)造函數(shù)
var ob1 ={c:{a:1,b:2}}; var ob2 =JSON.parse(JSON.stringfy(ob1)); //用JSON.stringify把對(duì)象轉(zhuǎn)成字符串,再用JSON.parse把字符串轉(zhuǎn)成新的對(duì)象
方法三、遞歸拷貝
function deepClone(obj1,obj2){ var obj = obj2|| {};//如果obj存在則定義為obj2,否則建立空對(duì)象 for(var i in obj1){//遍歷原對(duì)象 if(typeof obj1[i] === "object"){//如果當(dāng)前元素是對(duì)象 obj[i] = Array.isArray(obj1[i]) ?[]:{};//判斷是數(shù)組還是對(duì)象 deepClone(obj1[i],obj[i]);//利用遞歸逐層遍歷直到最后一層 } else{ obj[i] = obj1[i];//賦值 } } return obj; } var str = {}; var obj = { a: {a: "Leemo", b: 19980228} }; deepClone(obj, str); console.log(str.a);
方法四、使用Object.create()方法
var Obj2 = object.create(Obj1); //實(shí)現(xiàn)Obj2深拷貝Obj1
參考文檔:
文檔1
文檔2
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103555.html
摘要:接下來(lái)我們進(jìn)入正片數(shù)據(jù)類型六種基本數(shù)據(jù)類型布爾值,和一個(gè)表明值的特殊關(guān)鍵字。一種數(shù)據(jù)類型,它的實(shí)例是唯一且不可改變的。在中是沒(méi)有方法是可以改變布爾值和數(shù)字的。參考資料深拷貝淺拷貝 前言 筆者最近整理了一些前端技術(shù)文章,如果有興趣可以參考這里:muwoo blogs。接下來(lái)我們進(jìn)入正片: js 數(shù)據(jù)類型 六種 基本數(shù)據(jù)類型: Boolean. 布爾值,true 和 false. nu...
摘要:接下來(lái)我們進(jìn)入正片數(shù)據(jù)類型六種基本數(shù)據(jù)類型布爾值,和一個(gè)表明值的特殊關(guān)鍵字。一種數(shù)據(jù)類型,它的實(shí)例是唯一且不可改變的。在中是沒(méi)有方法是可以改變布爾值和數(shù)字的。參考資料深拷貝淺拷貝 前言 筆者最近整理了一些前端技術(shù)文章,如果有興趣可以參考這里:muwoo blogs。接下來(lái)我們進(jìn)入正片: js 數(shù)據(jù)類型 六種 基本數(shù)據(jù)類型: Boolean. 布爾值,true 和 false. nu...
摘要:接下來(lái)就讓我們更細(xì)致的探究中的深淺拷貝??偨Y(jié)以上對(duì)深拷貝和淺拷貝做了簡(jiǎn)單的介紹,在深拷貝的實(shí)現(xiàn)上也只介紹了最簡(jiǎn)單的實(shí)現(xiàn)形式,并未考慮復(fù)雜情況以及相應(yīng)優(yōu)化,想要對(duì)深拷貝有更深入的了解,需要大家花時(shí)間去深入研究,或者可以關(guān)注我后續(xù)文章的動(dòng)態(tài)。 對(duì)象和數(shù)組的拷貝對(duì)我來(lái)說(shuō)一直都是一個(gè)比較模糊的概念,一直有點(diǎn)一知半解,但是在實(shí)際工作中又偶爾會(huì)涉及到,有時(shí)候還會(huì)一不小心掉坑里,不知道大家有沒(méi)有同樣...
摘要:網(wǎng)上有很多方法,比如對(duì)象的和的等,但是它們有一個(gè)共同的問(wèn)題就是對(duì)簡(jiǎn)單對(duì)象可以實(shí)現(xiàn)深拷貝,但是對(duì)復(fù)雜對(duì)象就不行了,比如這樣一個(gè)對(duì)象屬性值有函數(shù)數(shù)組復(fù)雜對(duì)象等這個(gè)時(shí)候剛才那幾個(gè)方法就不行了。 以前對(duì)深拷貝和淺拷貝沒(méi)有太深的印象,后來(lái)才知道是因?yàn)闆](méi)掉進(jìn)去過(guò)它的坑里。最近掉坑了才意識(shí)到它們的重要性。 閑話少敘,來(lái)說(shuō)說(shuō)坑:如果我需要保存一個(gè)復(fù)雜的對(duì)象 obj 并把它賦值給 originalObj...
閱讀 2394·2023-04-25 19:27
閱讀 3505·2021-11-24 09:39
閱讀 3919·2021-10-08 10:17
閱讀 3409·2019-08-30 13:48
閱讀 1943·2019-08-29 12:26
閱讀 3132·2019-08-28 17:52
閱讀 3548·2019-08-26 14:01
閱讀 3543·2019-08-26 12:19