摘要:用擴展運算符深拷貝數組直接粘貼代碼當數組是一維數組時,擴展運算符可以進行完全深拷貝,改變拷貝后數組的值并不會影響拷貝源的值。對象同理當對象只有一層時可以用擴展運算符進行完全深拷貝。
數組和對象的拷貝方式有很多,此處只針對擴展運算符...對數組和對象的深拷貝方式進行說明。
用擴展運算符深拷貝數組:
直接粘貼代碼:
let arr = [1, 2, 3, 4, 5, 6]; let arr1 = [...arr]; arr1.push(7); console.log(arr); //[1, 2, 3, 4, 5, 6] console.log(arr1); //[1, 2, 3, 4, 5, 6, 7]
當數組是一維數組時,擴展運算符可以進行完全深拷貝,改變拷貝后數組的值并不會影響拷貝源的值。
但是,當數組為多維時:
let arr = [1, 2, 3, 4, 5, 6, [1, 2, 3]]; let arr1 = [...arr]; arr1.push(7); arr1[arr1.length - 2][0] = 100; console.log(arr); //[1, 2, 3, 4, 5, 6,[100, 2, 3]] console.log(arr1); //[1, 2, 3, 4, 5, 6, [100, 2, 3],7]
由上可見,我們不難發現當改變拷貝后數組中第二層數組的值時,arr1arr1.length - 2 = 100;拷貝前數組第二層數組的值也跟著改變了。
對象同理:
當對象只有一層時:
let obj = { name: "Wawa", age: 13, gender: "female" }; let obj1 = {...obj }; obj1.height = 165; console.log(obj);//{name: "Wawa", age: 13, gender: "female"} console.log(obj1);//{name: "Wawa", age: 13, gender: "female", height: 165}
可以用擴展運算符進行完全深拷貝。
但當對象有多層時:
let obj = { name: "Wawa", age: 13, gender: "female", hobby: { a: "Chinese", b: "Math", c: "English" } }; let obj1 = {...obj }; obj1.hobby.a = "PE"; console.log(obj); //{name: "Wawa", age: 13, gender: "female",hobby:{a: "PE", b: "Math", c: "English"}} console.log(obj1); //{name: "Wawa", age: 13, gender: "female", ,hobby:{a: "PE", b: "Math", c: "English"},height: 165}
擴展運算符并不能打散第二層對象的值,且無法對其進行深拷貝,拷貝前和拷貝后第二層對象的引用地址仍然是同一個,一方改變,另一方也改變。
結論:用擴展運算符對數組或者對象進行拷貝時,只能擴展和深拷貝第一層的值,對于第二層極其以后的值,擴展運算符將不能對其進行打散擴展,也不能對其進行深拷貝,即拷貝后和拷貝前第二層中的對象或者數組仍然引用的是同一個地址,其中一方改變,另一方也跟著改變。
另外有一個疑問,官方說用Object.assign()拷貝時是淺拷貝,可無論我怎么操作都是深拷貝的效果,望大家指出理解錯誤的地方,此處貼上測試的demo:
let obj3 = { name: "Gucci", age: 13, gender: "female", hobby: { a: "Chinese", b: "Math", c: "English" } }; let obj4 = Object.assign({}, obj3); obj4.hobby.a = "Math"; obj3.age = 1000; console.log(obj3); console.log(obj4.age);
無論是一層還是二層,改變拷貝之后屬性的值,拷貝前對象中的任何值并沒有發生改變,且互不影響,這不是深拷貝嗎???
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98532.html
摘要:深拷貝與淺拷貝的出現,就與這兩個數據類型有關。這時,就需要用淺拷貝來實現了。數據一但過多,就會有遞歸爆棧的風險。這個方法是在解決遞歸爆棧問題的基礎上,加以改進解決循環引用的問題。但如果你并不想保持引用,那就改用用于解決遞歸爆棧即可。 前言 這是前端面試題系列的第 9 篇,你可能錯過了前面的篇章,可以在這里找到: 數組去重(10 種濃縮版) JavaScript 中的事件機制(從原生到...
showImg(https://segmentfault.com/img/bVbvpCA); 前言 為什么寫拷貝這篇文章?同事有一天提到了拷貝,他說賦值就是一種淺拷貝方式,另一個同事說賦值和淺拷貝并不相同。我也有些疑惑,于是我去MDN搜一下拷貝相關內容,發現并沒有關于拷貝的實質概念,沒有辦法只能通過實踐了,同時去看一些前輩們的文章總結了這篇關于拷貝的內容,本文也屬于公眾號【程序員成長指北】學習路線...
摘要:深拷貝相比于淺拷貝速度較慢并且花銷較大。所以在賦值完成后,在棧內存就有兩個指針指向堆內存同一個數據。結果如下擴展運算符只能對一層進行深拷貝如果拷貝的層數超過了一層的話,那么就會進行淺拷貝那么我們可以看到和展開原算符對于深淺拷貝的結果是一樣。 JS中數據類型 基本數據類型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用數據類型:...
摘要:引用類型值引用類型值是保存在堆內存中的對象,變量保存的只是指向該內存的地址,在復制引用類型值的時候,其實只復制了指向該內存的地址。 前言 要理解 JavaScript中淺拷貝和深拷貝的區別,首先要明白JavaScript的數據類型。JavaScript有兩種數據類型,基礎數據類型和引用數據類型。js的基本類型:undefined,null,string,boolean,number,s...
摘要:而在這個運算符的相關用例中,往往會涉及到其他知識點,深拷貝和淺拷貝就是其中之一。即對象的淺拷貝會對主對象的值進行拷貝,而該值有可能是一個指針,指向內存中的同一個對象。,可以看到深拷貝和淺拷貝是對復制引用類型變量而言的。 在ES6的系列文章中,基本都會提到Spread——擴展運算符(...)。而在這個運算符的相關用例中,往往會涉及到其他知識點,深拷貝和淺拷貝就是其中之一。 背景知識 在討...
閱讀 2793·2021-10-11 10:57
閱讀 2402·2021-08-27 16:20
閱讀 1384·2019-08-30 13:03
閱讀 1563·2019-08-30 12:50
閱讀 3336·2019-08-29 14:16
閱讀 1561·2019-08-29 11:12
閱讀 1613·2019-08-28 17:53
閱讀 2893·2019-08-27 10:58