zoukankan      html  css  js  c++  java
  • JavaScript中:地址引用的特性,导致静态初始值被修改

    问题分类

    JavaScript,值引用,地址引用

    问题描述

    开发过程中,服务端将静态配置数据从mysql数据库中读取到内存中,方便调用。

    在实现流派功能时,需从数据库中读取流派种类数据到内存中,由于其中generals字段的值是一个转成了字符串类型的数组,因此需要使用JSON.Parse()解析该字段值,如图:

    image.png

     

    在实现接口后调用,第一次成功,但是继续请求第二次,就会报错,报错来源是JSON.parse()这里。

     

     

    原因分析

    从报错信息上看,是JSON.parse的对象类型不正确,导致无法parse,代码中generals的初始值等于'["zhubajie", "sunwukong", "niumowang", "jinjiao", "yinjiao"]',目前是要将该字符串解析成数组,第一次请求时,解析是成功的,但是第二次就失败报错,按设想是,每次请求时,

    都取一次内存中的初始配置数据,而初始配置理应是不会变化的,这样保证每次都可以正确解析。

    通过代码检查,看到了这段:

    (preGeneralGroup[key] as PreGeneralGroup).generals = JSON.parse((preGeneralGroup[key] as PreGeneralGroup).generals);

    这里将preGeneralGroup的属性generals重新赋值为数组类型的值,会不会是这里改变了初始配置数据呢?

    答案是会的,在JS中,有两种引用方式,一种是值引用,另一种是地址引用,其中:

    * 数字、字符串、布尔类型的为原始类型,是值引用

    * 数组、对象类型为地址引用

    * 值引用 可以深拷贝

    * 地址引用 循环到原始类型方可进行深拷贝

    而不巧的是我们上面代码中的初始配置就是一个对象,如下图:

    PreGeneralGroup类型定义:

    image.png

     

    因此下面这段代码,实际是地址引用:

    let preGeneralGroup: PreGeneralGroupCfg = dataApi.preGeneralGroup.data as PreGeneralGroupCfg;

    这就导致了当preGeneralGroup中的属性generals类型被改变时,初始配置dataApi.preGeneralGroup.data对象中的generals属性也被改变了进而导致了报错的产生。

     

    解决方案

    对需要引用的对象进行深度拷贝,不需要重新造轮子,可以直接使用现有工具包lodash中的cloneDeep()方法即可,如下图:

    image.png

     

     
     
     
  • 相关阅读:
    scrapy 随机UserAgent
    Scrapy使用中间件捕获Spider抛出的异常
    10.16-arrarylist
    10.15_package_2
    10.14_package_1
    10.13_enum_2
    10.12-enum_1
    10.11-java的接口2
    10.10-3对象和类_动手动脑-java的接口
    10.9-java的封装
  • 原文地址:https://www.cnblogs.com/yourstars/p/11970558.html
Copyright © 2011-2022 走看看