文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript 深拷贝的循环引用问题详解

2022-12-27 18:00

关注

如果说道实现深拷贝最简单的方法,我们第一个想到的就是 JSON.stringify() 方法,因为JSON.stringify()后返回的是字符串,所以我们会再使用JSON.parse()转换为对象,如下代码:

let obj = { name: 'liaoyi',age: 22,sex: 1}
JSON.parse(JSON.stringify(obj))

但是这种克隆不够完美,有一个致命的问题无法解决,就是她一旦遇到循环引用就会报错:

let obj = { name: 'liaoyi',age: 22,sex: 1}
JSON.parse(JSON.stringify(obj))
obj.c = obj
console.log(JSON.stringify(obj))

js会报错,无法把一个循环引用转成 json 格式:

在这种情况下,我们通常想到的是写一个正儿八经的深度克隆方法:

使用传统方式实现对象的深拷贝

function deepClone(obj) {
  const objectMap = new Map();
  const _deepClone = value => {
    const type = typeof value;
    if (type !== 'object' || type === null) {
      return value;
    }
    if (objectMap.has(value)) {
      return objectMap.get(value);
    }
    const result = Array.isArray(value) ? [] : {};

    objectMap.set(value, result);

    for (const [key, _v] of Object.entries(value)) {
      result[key] = _deepClone(value[key]);
      console.log(key, _v);
    }
    return result;
  };
  return _deepClone(obj);
}

使用 MessageChannel 实现循环引用对象的深拷贝

不够新鲜,我们来看一个好玩的 Web API

参考链接: MessageChannel

MessageChannel允许我们在不同的浏览上下文,比如window.open()打开的窗口或者iframe等之间建立通信管道,并通过两端的端口(port1和port2)发送消息。MessageChannel以DOM Event的形式发送消息,所以它属于异步的宏任务。

// 通过这个构造函数,创建一个消息通道,它会返回一个对象,解构 port1, port2 来实现通信
const { port1, port2 } = new MessageChannel();
port1.postMessage('hello')
port2.onmessage = msg => {
  console.log(msg.data)  // hello
}

我们可以利用这个API,实现循环引用对象的深拷贝:

 function deepClone(obj) {
  return new Promise(resolve => {
    const { port1, port2 } = new MessageChannel();
    port1.postMessage(obj);

    port2.onmessage = msg => {
      resolve(msg.data);
      // console.log(obj, msg.data === obj); // false
    };
  })
}

 const obj = { a: 1, b: '2' }
 obj.c = obj; 
 deepClone(obj).then(res =>{
  console.log('res',res);
 })

到此这篇关于JavaScript 深拷贝的循环引用问题 _的文章就介绍到这了,更多相关JavaScript 深拷贝内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯