广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Javascript深度克隆中的循环引用问题怎么解决
  • 562
分享到

Javascript深度克隆中的循环引用问题怎么解决

2024-04-02 19:04:59 562人浏览 安东尼
摘要

这篇文章主要介绍“javascript深度克隆中的循环引用问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript深度克隆中的循环引用问题怎么

这篇文章主要介绍“javascript深度克隆中的循环引用问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript深度克隆中的循环引用问题怎么解决”文章能帮助大家解决问题。

概要

前端项目开发中,我们经常需要深度克隆js对象。在克隆代码开发过程中,我们经常会遇到数组判定或对象循环引用的问题。

本文通过实例来解决上述问题

代码及实现

常见深度克隆JS对象的代码

function deepClone(origin){

    if (origin == undefined || typeof origin !== "object"){

        return origin;

    }

    if (origin instanceof Date){

        return new Date(origin);

    }

    let keys = Reflect.ownKeys(origin);

    let target = {};

    if (Object.prototype.toString.call(origin) === "[object Array]"){

        target = [];

    }

    for(let key of keys){

        target[key] = deepClone(origin[key]);

    }

    return target;

上述代码主要存在两个问题:

数组判定代码过于麻烦

对象中如果出现循环引用,代码将会报错。

循环引用代码:

var obj = {a: 1};

obj.obj1 = obj;

var newObj = deepClone(obj);

console.log(newObj);

错误信息:

产生错误的原因很简单,由于对象中存在循环引用,所以递归无法结束,最后内存溢出了。

循环引用问题的解决

由于对象中的循环引用,所以递归无法结束。如果我们记录下哪个对象被克隆了,哪个对象没有被克隆,就可以强制结束递归,避免内存泄漏。

我们选择WeekMap来记录对象是否被克隆,主要考虑以下三点:

WeakMap对象是key => value形式,不会重复记录

WeakMap对象的key必须是一个对象

WeakMap是若引用,如果不再使用,内存空间直接释放。

改进代码如下:

function deepClone(origin, map = new WeakMap()){

    if (origin == undefined || typeof origin !== "object"){

        return origin;

    }

    if (origin instanceof Date){

        return new Date(origin);

    }

    if (origin instanceof RegExp){

        return new RegExp(origin);

    }

    var copied = map.get(origin);

    if (!!copied){

        return copied;

    }   

    let target = {};

    if (Object.prototype.toString.call(origin) === "[object Array]"){

        target = [];

    }

    map.set(origin, target);

    let keys = Reflect.ownKeys(origin);

    for(let key of keys){   

        target[key] = deepClone(origin[key], map);

    }

    return target;

通过WeakMap记录对象是否被拷贝过,如果拷贝过,就直接将拷贝过的对象返回,不再重复克隆

如果没有被拷贝过,构建数组或普通JS对象,然后再进行记录。

克隆存在循环引用的对象,代码如下:

var obj = {a: 1};

obj.obj1 = obj;

var newObj = deepClone(obj);

console.log(newObj);

执行结果如下:

数组判定的代码优化

在克隆之前,我们必须知道要克隆的对象是一个普通JS对象还是一个数组。我们是否可以换一个思路,任何对象都有自己的构建器,如果我们直接使用构造器构造对象,也就不需要之前对象是什么类型了。

JS中所有对象都有自己的原型链,原型链中包含基类Object的构造器,如下所示:

JS普通对象

JS数组:

JS普通对象的构造方法可以构建出{},JS数组的构建方法可以构造出[]。所以如果我们调用该构造方法,就无需再去判定数组还是普通对象了。

改进后的代码如下:

function deepClone(origin, map = new WeakMap()){

    if (origin == undefined || typeof origin !== "object"){

        return origin;

    }

    if (origin instanceof Date){

        return new Date(origin);

    }

    var copied = map.get(origin);

    if (!!copied){

        return copied;

    }   

    let target = new origin.constructor();

    map.set(origin, target);

    let keys = Reflect.ownKeys(origin);

    for(let key of keys){   

        target[key] = deepClone(origin[key], map);

    }

    return target;

关于“Javascript深度克隆中的循环引用问题怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网JavaScript频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: Javascript深度克隆中的循环引用问题怎么解决

本文链接: https://www.lsjlt.com/news/90867.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Javascript深度克隆中的循环引用问题怎么解决
    这篇文章主要介绍“Javascript深度克隆中的循环引用问题怎么解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Javascript深度克隆中的循环引用问题怎么...
    99+
    2022-10-19
  • JavaScript 深拷贝的循环引用问题详解
    如果说道实现深拷贝最简单的方法,我们第一个想到的就是 JSON.stringify() 方法,因为JSON.stringify()后返回的是字符串,所以我们会再使用JSON.pars...
    99+
    2022-12-27
    JavaScript 深拷贝 JavaScript 深拷贝循环引用 JS循环引用
  • Java循环引用问题怎么解决
    在Java中,循环引用问题通常是指两个或多个对象相互引用,导致无法被垃圾回收器回收,从而造成内存泄漏的情况。要解决循环引用问题,可以...
    99+
    2023-10-07
    Java
  • 使用JSON.stringify时遇到的循环引用问题怎么解决
    这篇文章给大家分享的是有关使用JSON.stringify时遇到的循环引用问题怎么解决的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。程序员在日常做TypeScript/JavaScript开发时,经常需要将复杂的...
    99+
    2023-06-14
  • java中怎么利用lambda解决foreach循环问题
    本篇文章给大家分享的是有关java中怎么利用lambda解决foreach循环问题,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。一、以前我们使用的for循环 &nbs...
    99+
    2023-06-20
  • Java中Map循环遍历的效率问题怎么解决
    在Java中,Map的循环遍历可以通过使用不同的方法来提高效率:1. 使用entrySet()方法遍历:遍历Map的entrySet...
    99+
    2023-08-15
    Java Map
  • 怎么解决引用slf4j中Logger.info没有数据的问题
    这篇文章主要介绍“怎么解决引用slf4j中Logger.info没有数据的问题”,在日常操作中,相信很多人在怎么解决引用slf4j中Logger.info没有数据的问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作