JS的深淺復制詳細
1、淺復制的意思
淺復制是僅僅對數據存放在棧內的引用的復制,沒有復制引用指向堆內的內容。多個數據的淺復制,這復制多個引用,這多個引用共同指向堆內的同一個內容。當一個淺復制數據做出修改,即堆內的引用指向的內容發生修改,這時,其他通過引用指向這裡的數據也會隨著改變。
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = obj; objA.a = 'a'; console.log(obj.a); // 'a' console.log(objA.a); // 'a'
2、深復制的意思
深復制是指連同堆的內容一塊復制,生成一個新的對象。多個深復制將是多個不同的對象,也就有不同的引用,也就指向不同的堆內容。
3、使用深復制的原由
在平常開發中,有時會有數據的傳遞與接收,當拿到傳過來的數據後,難免需要對數據進行加工和改造,為瞭不破壞原有數據結構,這時就可以使用深復制拷貝數據,然後處理生成的新的數據。深復制也可以防止修改多個引用後引用混亂的問題,減少BUG
的產生機會。
4、可實現深復制的幾種方法
實現方式一:JSON的序列化與反序列化
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = JSON.parse(JSON.stringify(obj));//JSON的序列化與反序列化 objA.a = 'a'; console.log(obj.a); // 1 console.log(objA.a); // 'a'
雖然JSON
的序列化與反序列化可以實現深復制,但有幾個缺點需要註意:
date
日期對象被轉成日期日期字符串- 沒法訪問到原型
- 復制不瞭
undefined
的屬性 NAN
和無窮被轉為NULL
let d1 = new Date(); let obj = { d1, d2: undefined, d3:NaN } let objD = JSON.parse(JSON.stringify(obj)); console.log(obj) console.log(objD)
實現方式二:Object.assign()
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = Object.assign(obj); objA.a = 'a'; console.log(obj.a); // 1 console.log(objA.a); // 'a'
雖然Object.assign()
可以實現深復制,但對於更深層次的對象引用也是僅僅淺復制。
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = Object.assign(obj); objA.c.c1 = 'c1'; //Object.assign()僅僅是一層深復制。 console.log(obj.c.c1); // 'c1' console.log(objA.c.c1); // 'c1'
實現方式三:擴展運算符
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = {...obj};; objA.a = 'a'; console.log(obj.a); // 1 console.log(objA.a); // 'a'
雖然擴展運算符” …
“可以實現深復制,但對於更深層次的對象引用也是僅僅淺復制。
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = {...obj}; objA.c.c1 = 'c1'; //擴展運算符"..."同Object.assign()一樣,僅僅是一層深復制,不能多層深復制。 console.log(obj.c.c1); // 'c1' console.log(objA.c.c1); // 'c1'
實現方式四:使用遞歸
想要實現深復制,且實現多層深復制則可以使用遞歸循環復制。
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } const ReCopy = function (paramter) { let target = null; let isObject = paramter.constructor === Object; let isArray = paramter.constructor === Array; if (isObject || isArray) { target = Array.isArray(paramter) ? [] : {}; for (let i in paramter) { target[i] = ReCopy(paramter[i]); } } else { target = paramter; } return target; } let objA = ReCopy(obj); objA.c.c1 = 'c1'; console.log(obj.c.c1); // 10 console.log(objA.c.c1); // 'c1'
5、ladash深拷貝
lodash
深復制是更專業的深復制方式。
安裝lodash
先初始化,生成package.json
文件,然後使用一下命令安裝。
npm i -S lodash
引入lodash
var _ = require('lodash');
使用lodash
let obj = { a:1, b:2, c:{ c1:10, c2:20 } } let objA = _.cloneDeep(obj); objA.c.c1 = 'c1'; console.log(obj.c.c1); // 10 console.log(objA.c.c1); // 'c1'
到此這篇關於JS的深淺復制詳細的文章就介紹到這瞭,更多相關JS的深淺復制內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!