使用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.port1channel.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
原文转载:http://www.shaoqun.com/a/502699.html
landing:https://www.ikjzd.com/w/2368
let go:https://www.ikjzd.com/w/825
使用JSON.parse(JSON.stringify(object))实现深拷贝局限大部分情况我们都可以使用JSON.parse(JSON.stringify(object))来实现深拷贝,但该方法也有局限性,如下:会忽略undefined会忽略symbol不能序列化函数不能解决循环引用的对象例如:leta={age:undefined,sex:Symbol('male'),jo
catch:catch
mil:mil
江城文艺青年必去地:江城文艺青年必去地
亚马逊卖家写标题的常用几个主流套路:亚马逊卖家写标题的常用几个主流套路
做好亚马逊的本质是什么,资深大卖给你来解密!:做好亚马逊的本质是什么,资深大卖给你来解密!
No comments:
Post a Comment