使用JSON.parse(JSON.stringify(object))實作深拷貝局限
大部分情況我們都可以使用JSON.parse(JSON.stringify(object))來實作深拷貝,但該方法也有局限性,如下:
- 會忽略
undefined - 會忽略
symbol - 不能序列化函式
- 不能解決回圈參考的物件
例如:
let a = { age: undefined, sex: Symbol('male'), jobs: function() {}, name: 'yck' } let b = JSON.parse(JSON.stringify(a)) console.log(b) // {name: "yck"}
借用 MessageChannel 實作深拷貝
MessageChannel API允許我們創建一個新的訊息通道,并通過它的兩個MessagePort屬性發送資料,
var channel = new MessageChannel();
這樣就創建了一個管道,
實體屬性:
channel.port1
channel.port2
獲取實體的兩個埠,注意的是,兩個埠都是只讀的,
簡單來說,MessageChannel創建了一個通信的管道,這個管道有兩個埠,每個埠都可以通過postMessage發送資料,而一個埠只要系結了onmessage回呼方法,就可以接收從另一個埠傳過來的資料,
一個簡單的例子:
var channel = new MessageChannel(); var port1 = channel.port1; var port2 = channel.port2; port1.onmessage = function(event) { console.log("port1收到來自port2的資料:" + event.data); } port2.onmessage = function(event) { console.log("port2收到來自port1的資料:" + event.data); } port1.postMessage("發送給port2"); port2.postMessage("發送給port1");
而通過 postMessage() 方法傳輸的 message 引數是深拷貝的,
function deepClone(val) { return new Promise((resolve,reject) => { const {port1,port2} = new MessageChannel(); port2.onmessage = e => resolve(e.data); port1.postMessage(val); }) } let obj = { age: undefined, name: 'yck', c: { d: true } } obj.c.e = obj.c; // 回圈參考 // 注意該方法是異步 async function test() { const clone = await deepClone(obj); console.log(clone) // {age: undefined, name: "yck", c: {…}} } test()
但這個深拷貝只能解決 undefined 和回圈參考物件的問題,對于 Symbol 和 function 依然束手無策,
詳細可參考:《MessageChannel 訊息通道》
簡易版的深拷貝
var extendCopy = (function f(p,c){ var c = c || {}; for (var i in p) { if(typeof p[i] === 'object'){ c[i] = (p[i] instanceof Array) ? [] : {}; f(p[i],c[i]); }else{ c[i] = p[i]; } } return c; });
詳細可參考:《小tips:JS之淺拷貝與深拷貝》
lodash 的深拷貝函式
語法:
_.cloneDeep(value)
示例:
var objects = [{ 'a': 1 }, { 'b': 2 }]; var deep = _.cloneDeep(objects); console.log(deep[0] === objects[0]); // => false
地址:https://lodash.com/docs/4.17.15#cloneDeep
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/239036.html
標籤:其他
上一篇:小tips:使用JSON.parse(JSON.stringify(object))實作深拷貝的局限及擴展
下一篇:2020年數控行業方案盤點
