JavaScript,值引用,地址引用
开发过程中,服务端将静态配置数据从mysql数据库中读取到内存中,方便调用。
在实现流派功能时,需从数据库中读取流派种类数据到内存中,由于其中generals字段的值是一个转成了字符串类型的数组,因此需要使用JSON.Parse()解析该字段值,如图:
在实现接口后调用,第一次成功,但是继续请求第二次,就会报错,报错来源是JSON.parse()这里。
从报错信息上看,是JSON.parse的对象类型不正确,导致无法parse,代码中generals的初始值等于'["zhubajie", "sunwukong", "niumowang", "jinjiao", "yinjiao"]',目前是要将该字符串解析成数组,第一次请求时,解析是成功的,但是第二次就失败报错,按设想是,每次请求时,
都取一次内存中的初始配置数据,而初始配置理应是不会变化的,这样保证每次都可以正确解析。
通过代码检查,看到了这段:
这里将preGeneralGroup的属性generals重新赋值为数组类型的值,会不会是这里改变了初始配置数据呢?
答案是会的,在JS中,有两种引用方式,一种是值引用,另一种是地址引用,其中:
* 数字、字符串、布尔类型的为原始类型,是值引用
* 数组、对象类型为地址引用
* 值引用 可以深拷贝
* 地址引用 循环到原始类型方可进行深拷贝
而不巧的是我们上面代码中的初始配置就是一个对象,如下图:
PreGeneralGroup类型定义:
因此下面这段代码,实际是地址引用:
这就导致了当preGeneralGroup中的属性generals类型被改变时,初始配置dataApi.preGeneralGroup.data对象中的generals属性也被改变了进而导致了报错的产生。
对需要引用的对象进行深度拷贝,不需要重新造轮子,可以直接使用现有工具包lodash中的cloneDeep()方法即可,如下图: