摘要:中的深拷貝與淺拷貝說到深淺拷貝的時候就不得不說一下中的變量類型了基本類型按值存放在棧內存中的簡單數據段可以直接訪問引用類型存放在堆內存中的對象變量保存的是一個指向存放數據位置的指針訪問引用類型的值時首先從棧中獲取到存放該數據位置的指針然后再
JS中的深拷貝與淺拷貝
說到深淺拷貝的時候就不得不說一下JS中的變量類型了:
基本類型: undefined、null、boolean、number、string, 按值存放在棧內存中的簡單數據段, 可以直接訪問.
引用類型: 存放在堆內存中的對象, 變量保存的是一個指向存放數據位置的指針. 訪問引用類型(object, array)的值時, 首先從棧中獲取到存放該數據位置的指針, 然后再從堆中取得數據.
__淺拷貝__: 淺拷貝是拷貝引用, 拷貝后的引用都是指向同一個存放數據位置的指針, 無論操作哪一個都是在操作指向在堆中的那一個數據, 所以雙方都會有影響.
__深拷貝__: 在堆中重新分配內存, 將源對象的各個屬性復制進去. 對拷貝對象和源對象各自操作互不影響.
淺拷貝淺拷貝分兩種情況, 拷貝源對象的引用和源對象拷貝實例, 但其屬性拷貝引用.
拷貝源的引用
eg:
let obj1 = { a: 1 }; let obj2 = obj1; console.log(obj1 === obj2); // true obj1.a = 2; console.log(obj2.a); // 2
源對象拷貝實例, 其屬性對象拷貝引用
外層源對象是拷貝實例, 但是如果源對象的屬性元素為復雜數據類型時, 內層元素拷貝引用. 對源對象操作時不影響拷貝對象. 但對其屬性操作時, 會改變拷貝對象屬性的值. 常用方法: Array.prototype.slice(), Array.prototype.concat(), jQuery的$.extend({}, obj), Object.assign()等. eg:
let obj1 = { a: 1, b: [1, 2, 3], c: { c1: 1 } }; let obj2 = Object.assign({}, obj1); obj2.a = 2; obj2.b[0] = 2; obj2.c.c1 = 10 console.log(obj1); /** 輸出結果: { a: 1, b: [2, 2, 3], c: { c1: 10 } } **/
這上面的例子中obj1為源對象, obj2為拷貝對象. 拷貝后修改拷貝對象的屬性a沒有影響到源對象, 修改拷貝對象的復雜數據類型屬性b, c后影響到源對象.
深拷貝深拷貝過后, 源對象、拷貝對象包括其內部元素(包括復雜類型元素)都不互相干擾. 常見方法有JSON.parse(JSON.stringify(obj)), jQuery的$.extend(true, {}, obj), lodash的_.cloneDeep和_clone(value, true). eg:
let obj1 = { a: 1, b: [1, 2, 3], c: { c1: 1 } }; let obj2 = JSON.parse(JSON.stringify(obj1)); obj2.a = 2; obj2.b[0] = 2; obj2.c.c1 = 10 console.log(obj1); /** 輸出結果: { a: 1, b: [1, 2, 3], c: { c1: 1 } } **/
最后輸出源對象(obj1) 得到結果是源對象未變化.
深拷貝就是增加一個指針(棧內存)申請一個新的堆內存, 并讓這個指針指向這個堆內存. 當我們需要復制源對象而又不能修改源對象的時候, 深拷貝就是你想要的.
那么是時候自己實現一個深拷貝方法了:
function deepclone(sObj, cObj) { cObj = cObj || (Array.isArray(sObj) ? [] : {}); for(let i in sObj) { if(typeof sObj[i] === "object") { cObj[i] = Array.isArray(sObj[i]) ? [] : {}; deepclone(sObj[i], cObj[i]) } else { cObj[i] = sObj[i] } }; return cObj; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108253.html
摘要:什么是深拷貝淺拷貝見名知義,無論是深拷貝還是淺拷貝,都是的問題。使用如下以上就是關于中的深拷貝與淺拷貝的知識和如何進行深拷貝的知識了,如果有錯或者有其他方式的話,歡迎在下面留言評論啦 前言 最近在寫項目的時候涉及到一些父子組件傳遞個對象或者數組通信啥的,或者是直接復制添加對象啥的,直接使用賦值的時候總會出錯。一查原來是淺拷貝的問題,就從網上找了點資料,匯總到這里來了。 1 什么是深拷貝...
摘要:深拷貝和淺拷貝最根本的區別在于是否是真正獲取了一個對象的復制實體,而不是引用,深拷貝在計算機中開辟了一塊內存地址用于存放復制的對象,而淺拷貝僅僅是指向被復制的內存地址,如果原地址中對象被改變了,那么淺拷貝出來的對象也會相應改變。 深拷貝和淺拷貝最根本的區別在于是否是真正獲取了一個對象的復制實體,而不是引用, 深拷貝在計算機中開辟了一塊內存地址用于存放復制的對象, 而淺拷貝僅僅是指向被...
摘要:案例中的賦值就是典型的淺拷貝,并且深拷貝與淺拷貝的概念只存在于引用類型。修改修改經測試,也只能實現一維對象的深拷貝。經過驗證,我們發現提供的自有方法并不能徹底解決的深拷貝問題。 在說深拷貝與淺拷貝前,我們先看兩個簡單的案例: //案例1 var num1 = 1, num2 = num1; console.log(num1) //1 console.log(num2) //1 num...
摘要:而引用類型值是指那些保存堆內存中的對象,意思是變量中保存的實際上只是一個指針,這個指針指向內存中的另一個位置,該位置保存對象。而堆內存主要負責對象這種變量類型的存儲。我們需要明確一點,深拷貝與淺拷貝的概念只存在于引用類型。 深拷貝和淺拷貝 說起深拷貝和淺拷貝,首先我們來看兩個栗子 // 栗子1 var a = 1,b=a; console.log(a); console.log(b) ...
摘要:深拷貝淺拷貝本文主要對深拷貝淺拷貝的解釋及實現做一下簡單記錄。之所以會有深拷貝與淺拷貝之分,是因為不同數據類型的數據在內存中的存儲區域不一樣。但注意,只能做一層屬性的淺拷貝。 深拷貝VS淺拷貝 本文主要對深拷貝&淺拷貝的解釋及實現做一下簡單記錄。原文鏈接,歡迎star。 之所以會有深拷貝與淺拷貝之分,是因為不同數據類型的數據在內存中的存儲區域不一樣。 堆和棧是計算機中劃分出來用來存儲的...
閱讀 3512·2021-11-15 11:38
閱讀 824·2021-11-08 13:27
閱讀 2235·2021-07-29 14:50
閱讀 2969·2019-08-29 13:06
閱讀 838·2019-08-29 11:22
閱讀 2408·2019-08-29 11:04
閱讀 3499·2019-08-28 18:23
閱讀 890·2019-08-26 13:46