js 对象深拷贝、对象数组深拷贝的几种方法总结
寫前端的時候經常會遇到對象的拷貝,一般我們會用到深拷貝,深拷貝就是完完整整的將一個對象從內存中拷貝一份出來,放到另一塊新開辟的內存中去。向下面這種賦值是淺拷貝,a、b都是對同一塊內存進行引用,a、b哪一個變量修改對象的屬性值都會相互影響。總結一下常用的對象深拷貝以及數組對象的深拷貝。
var a = {id:"",name:""} var b = a;1. 序列化轉成json字符串深拷貝,以及存在的問題
2. Object.assign()深拷貝,以及存在的問題
3. 循環遞歸深拷貝
一、序列化轉成json字符串深拷貝
例:
let source = {"id":1}; //序列化轉成json字符串 let jsonStr = JSON.stringify(source) //反序列化為對象 let target = JSON.parse(jsonStr);存在的問題:
此方法僅在原對象包含可序列化值類型且沒有任何循環引用時才有效。不可序列化值類型的一個例子是 Date 對象 - JSON.parse 只能將其解析為字符串而無法解析回其原始的 Date 對象
注:
同時總結java的序列化
序列化:就是把一個java對象轉成字節流
反序列化:就是把字節流轉成java對象
當然序列化不僅僅可以是轉成字節流或者json字符串,還有很多種方式
為什么在java對象要序列化,什么場景要序列化?
如果沒有序列化,怎么把一個在內存里面的對象保存到文件里面去,怎么把內存的對象通過網絡傳輸到另一臺計算機的內存去呢?序列化就是把內存的對象轉成字節流或者json字符串等方式進行傳輸用的,用在一些保存對象到文件、網絡傳輸對象等io流傳輸對象的場景。
二、Object.assign()深拷貝
Object.assign() 方法用于將所有可枚舉屬性的值從一個或多個源對象復制到目標對象。它將返回目標對象。
基本語法:Object.assign(target, …sources)
例:
這樣就可以把source對象里面的相同屬性值拷貝到target對象
存在的問題:
如果要拷貝的對象source里面的屬性不是基礎類型也是對象,或者屬性含有對象數組,這種方式的拷貝就不會把source對象里面的對象或者數組對象進行深拷貝
例:
這時target里面的屬性list數組對象只是淺拷貝source里面的list,還是對同一塊內存的引用
也可以向下面這樣優化,循環list數組里面的對象進行Object.assign拷貝,添加到一個新的數組去,然后再賦值給target.list
例:
注:如果對象里面還含有對象屬性,而里面的對象屬性又含有對象屬性,則這種方式很麻煩不合適。
三、循環遞歸深拷貝
function deepClone(obj, newObj) {var newObj = newObj || {};for (let key in obj) {if (typeof obj[key] == 'object') {let isArray = Array.isArray(obj[key]);//判斷是否數組newObj[key] = (isArray == true ? [] : {})deepClone(obj[key], newObj[key]);} else {newObj[key] = obj[key]}}return newObj; }參考:
網友haogemr的js 深度拷貝的幾種方法
總結
以上是生活随笔為你收集整理的js 对象深拷贝、对象数组深拷贝的几种方法总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2010出现fatal error
- 下一篇: 【连载】跨越时代的度量衡——Pandor