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