<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
深淺拷貝:
記憶體中一共分為棧記憶體和堆記憶體兩大區域,所謂深淺拷貝主要是對js參照型別資料進行拷貝一份,淺拷貝就是參照型別資料相互賦值之後,例obj1=obj2;如果後面的操作中修改obj1或者obj2,這個時候資料是會進行相應的變化的,因為在記憶體中參照型別資料是儲存在堆記憶體中,堆記憶體中存放的是參照型別的值,同時會有一個指標地址指向棧記憶體,兩個參照型別資料地址一樣,如果其中一個發生變化另外一個都會有影響;而深拷貝則不會,深拷貝是會在堆記憶體中重新開闢一塊空間進行存放;
簡單來說就是B複製了A,如果A發生了改變,如果B隨之變化,那麼是淺拷貝,如果B並沒有發生變化,則是深拷貝。
let a = 1; let b = a; b = 2; console.log(a);//1 console.log(b);//2
a,b都是屬於基本型別,基本型別的複製是不會影響對方的,因為基本型別是每一次建立變數都會在棧記憶體中開闢一塊記憶體,用來存放值,所以對基本型別進行拷貝是不會對另外一個變數有影響的,屬於深拷貝。
// concat() let list = ['a','b','c']; let list2 = list.concat(); list2.push('d') console.log(list);//['a','b','c'] console.log(list2);//['a','b','c','d'] // slice() let list = ['a','b','c']; let list2 = list.slice(); list2.push('d') console.log(list);//['a','b','c'] console.log(list2);//['a','b','c','d']
上面兩種方法只能實現陣列型別裡面的單層深拷貝,如果是多層無法實現深拷貝。
//二維陣列 let list = ['a','b','c',['d','e','f']]; let list2 = list.concat(); list2[3][0] = 'a'; console.log(list); console.log(list2);
可以看到原二維陣列的值也發生了變化,說明沒有實現深拷貝。
由此總結,concat和slice只能實現一維陣列的深拷貝,不能對多維陣列進行深拷貝,所以並不是一個完美的深拷貝方式。
let a = {id:1,name:'a',obj:{id:999}}; let b = new Object(); b.id = a.id; b.name = a.name; b.obj = a.obj; a.name = 'b'; a.obj.id = 888; console.log(a); console.log(b);
a.name更改並沒有影響到b.name,好像可以看作深拷貝,但第二層obj裡面裡面的id隨之更改了,因此其實並不是深拷貝。
let a = {id:1,name:'a',obj:{id:999}}; function fun(obj){ let o = {}; Object.assign(o,obj); return o; } let a2 = fun(a); a2.name ='a2'; a2.obj.id = 888; console.log(a); console.log(a2);
以上兩種方法,對於一層物件都能實現深拷貝,但對於多層物件則無法實現,因此也不是一種完美的深拷貝方式。
let a = { name : 'a', age : 20, obj : {id:999}, action : function(){ console.log(this.name); } } let b = JSON.parse(JSON.stringify(a)); a.name = 'b'; a.obj.id = 888; console.log(a); console.log(b);
單層物件name和多層物件obj.id的改變都沒影響到原物件,因此是一個比較完美的深拷貝,但是能看到function好像並沒有被拷貝。
可以看出這個方法對於一層和多層都能實現深拷貝,但是這個方法的缺陷是不能拷貝Function,所以在使用時,一定要注意資料型別。
let a = { name:'a', skin:["red","blue","yellow",["123","456"]], child:{ work:'none', obj:{ id:999 } }, action:function(){ console.log(this.name); } } //封裝的遞迴方法 function copyWid(obj){ let newObj = Array.isArray(obj)?[]:{}; for (var i in obj){ if(typeof obj[i] === 'object'){ //判斷是不是物件(陣列或物件) newObj[i] = copyWid(obj[i]) //遞迴解決多層拷貝 }else{ newObj[i] = obj[i] } } return newObj; }; let b = copyWid(a); b.child.obj.id =888; b.skin[3][0] = "pink"; console.log(a); console.log(b);
可以看到,無論是多層的物件還是多層的陣列,都能實現深拷貝,而且能拷貝函數,這個是目前來說最完美的深拷貝方法。
通過這個遞迴能實現一個比較完美的深拷貝,能彌補上述提到的所有方法中的缺點。
let a = {name:'a',id:99};//如果是陣列[xx,xx,xx],{...a}需要改成[...a] let b ={...a}; //[...a] a.id =88; console.log(a); console.log(b);
這個方法能實現物件陣列單層時的深拷貝,但是多層無法實現深拷貝。
以上這麼多方法,最優解應該屬於JSON和遞迴的方法(遞迴解決了JSON無法拷貝函數方法的問題),但是根據需求資料型別的不同,可以選擇更簡單的方式。
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45