js物件深複製
1.使用slice或者concat進行陣列深複製
對於值都是普通資料型別的陣列,可以使用陣列的slice或者concat函式來進行深複製。
let a = [1, 2, 3]let b = a.slice(0) //或者 let b = a.concat()b[0] = 0console.log(a[0] === 1) //true,改變b不影響a
若陣列的項不是普通資料型別,而是引用資料型別,則使用slice或concat進行複製則只能進行一層深複製,也就是陣列項內部不能進行深複製。如下,陣列第一項為一個物件,改變b陣列第一項中物件的key屬性值,對應的a陣列也被改變了。
let a = [{ key: 1}]let b = a.slice(0) //或者 let b = a.concat()b[0].key = 0console.log(a[0].key === 0) //true,改變b影響a
2.使用JSON序列化函式進行深複製
function deepColne(obj) { return JSON.parse(JSON.stringify(obj)) }
1.支援陣列和常規物件深複製
let obj = [{ key: 1}]let newObj = colne(obj) newObj[0].key = 0console.log(obj[0].key) // 1
2.不支援undefined,會轉成null
let a = [1, , 2]let b = colne(a)console.log(a[1]) // undefinedconsole.log(b[1]) // null
3.不支援函式、RegExp、Date物件,會報錯
let func = function() { console.log(1) }let newFunc = colne(func) //這直接報錯
3.使用遞迴進行物件深複製(遞迴為深度優先)
function deepColne(obj) { let newObj if(obj === null) { return null } else if (! (obj instanceof Object)) { return obj } else if (obj instanceof Date) { return new Date(obj) } else if (obj instanceof RegExp) { return new RegExp(obj) } else if (obj instanceof Function) { //經測試複製函式有問題 return eval(obj.toString()) } else if (obj instanceof Array) { newObj = [] for(item of obj) { newObj.push(clone(item)) } } else { newObj = Object.create(null) for(let key of Object.keys(obj)) { newObj[key] = clone(obj[key]) } } return newObj }
-缺陷:1)經測試函式複製有問題;2)不支援環的情況:物件的某個屬性值是物件本身,若出現環會迴圈遞迴,造成記憶體溢位。
4.使用寬度優先 + 佇列實現深複製,解決出現環的問題
-注意:不支援函式
function deepClone(obj) { if(obj === null) { return null } /*obj是Date型別 */ else if (obj instanceof Date) { return new Date(obj) } /*obj是正規表示式型別 */ else if (obj instanceof RegExp) { return new RegExp(obj) } /*obj是陣列或者普通物件*/ let newObj = (obj instanceof Array) ? [] : {}, srcQueue = [obj], srcVisitedQueue = [], copyQueue = [newObj], copyVisitedQueue = []; while (srcQueue.length > 0) { let currentSrcElement = srcQueue.shift(), currentCopyElement = copyQueue.shift(); srcVisitedQueue.push(currentSrcElement); copyVisitedQueue.push(currentCopyElement); for (let key in currentSrcElement) { /*基礎資料型別直接複製*/ if (typeof currentSrcElement[key] !== 'object') { currentCopyElement[key] = currentSrcElement[key]; } /*日期物件*/ else if (currentSrcElement[key] instanceof Date) { currentCopyElement[key] = new Date(currentSrcElement[key]) } /*正則*/ else if (currentSrcElement[key] instanceof RegExp) { currentCopyElement[key] = new RegExp(currentSrcElement[key]) } /*物件資料型別或者陣列*/ else { // 有環的情況:判斷該物件是否已被訪問 let index = srcVisitedQueue.indexOf(currentSrcElement[key]); if (index >= 0) { currentCopyElement[key] = copyVisitedQueue[index]; //環(已訪問)直接複製 } else { //非環物件或陣列加入到源佇列 srcQueue.push(currentSrcElement[key]); //copy物件對應位置暫時放置空物件或空陣列,下一輪迴圈賦值 currentCopyElement[key] = currentSrcElement[key] instanceof Array ? [] : {}; copyQueue.push(currentCopyElement[key]); } } } } return newObj }
作者:WHU_GIS_LJ
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1978/viewspace-2815223/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JS物件複製:深複製和淺複製JS物件
- JS 物件如何實現深複製JS物件
- js 實現深複製/深複製JS
- 淺談JS中物件的淺複製和深複製JS物件
- js 深複製JS
- vue物件的深層複製Vue物件
- js 淺拷貝(淺複製、淺克隆)、深拷貝(深複製、深克隆)JS
- C#中的物件深複製和淺複製C#物件
- 對於複製普通物件 深複製和淺複製是否一樣物件
- Java中物件的深複製和淺複製詳解Java物件
- js深度複製物件JS物件
- CoffeeScript攻略2.1:克隆物件(深複製)物件
- js物件的複製方法JS物件
- JS物件深度克隆/複製JS物件
- es6完全深複製一個物件物件
- js 淺複製和深複製的區別和應用JS
- Java引用複製、淺複製、深複製Java
- 寫個JS深複製,面試備用JS面試
- VUE js中複製物件 JSONVue物件JSON
- JavaScript 淺複製和深複製JavaScript
- 【web前端】用javascript實現物件的深複製Web前端JavaScript物件
- JS 複製陣列和物件JS陣列物件
- js陣列物件複製拷貝不改變原來的值,深拷貝JS陣列物件
- [分享]javascript 陣列以及物件的深拷貝(複製陣列或複製物件)的方法JavaScript陣列物件
- 淺複製和深複製的概念與值複製和指標複製(引用複製)有關 淺複製 “指標複製 深複製 值複製指標
- go slice深複製和淺複製Go
- c#淺複製與深複製C#
- go的深複製跟淺複製Go
- python 淺複製、深複製坑Python
- python 深複製和淺複製Python
- JavaScript中的淺複製與深複製JavaScript
- Vue實現對陣列、物件的深拷貝、複製Vue陣列物件
- 複製物件物件
- 25. 深淺複製
- 【JavaScript】聊一聊js中的淺複製與深複製與手寫實現JavaScriptJS
- Day 7.5 資料型別總結 + 複製 淺複製 深複製資料型別
- 詳談Javascript中的深複製和淺複製JavaScript
- Python 列表切片陷阱:引用、複製與深複製Python