由于以前一直使用的是 Pascal 开发,对于js中的存在的深拷贝、浅拷贝不知道。对于delphi来说,基本变量也好,结构变量也好,赋值就相当于拷贝了一份。
例如:
a := 1;
b := a;
//此时打印a,b分别是 1,1
a := 5;
//此时打印a,b分别是 5,1 也就是说b 只是拷贝了当时的a的值,以后a变化不会引起b变化
如果一定要a变化,也要引起b变化,delphi中需要明确指出需要指针、指针、指针。一般不用指针的话就是简单的拷贝。
但是在js中,做了一个项目,因为对js深拷贝、浅拷贝的知识盲点,导致程序bug很久没有解决,遇到了一个坑。js中是没有指针的概念的,但是js中基本类型变量的赋值就相当于delphi的变量赋值,对象、数组等赋值却相当于delphi中的指针指向,这个区别就比较大。
坑的场景是:在vue中有两个对象(JSON),分别是Applicant(投保人)和Insured(被保人),两个对象的结构定义是一样的:
//1. 投保人相关
applicant: {
name: 'sensor', //投保人姓名
cardtype: '1', //证件类型
cardno: '4401', // 证件号码
sex: '1', //性别
birthday: '1980-01-01', //出生日期
mobile: '1334****390', //手机号码
email: 'sen@abc.com', //邮箱
address: '', //地址
},
//2. 被保人
insured: {
name: 'sensor', //投保人姓名
cardtype: '1', //证件类型
cardno: '3203', // 证件号码
sex: '1', //性别
birthday: '1980-01-01', //出生日期
mobile: '133****390', //手机号码
email: 'ser@abc.com', //邮箱
address: '', //地址
}
在界面上进行了录入要素绑定,当投保人和被保人是同一个人时(界面上有switch确定是否是一个人),被保人信息录入界面不出现,隐藏起来;当投保人和被保人不是同一人时,两个录入信息界面都会显示出来。出现的bug现象是,在某种情况下修改被保人信息,投保人信息也同步更改,修改投保人信息,被保人信息也同步更改,这不是我们期望的结果。我们测试又很难测试出来,可是现场使用人员有时会出现。一直困扰我们的开发人员(注意目前没有办法在电脑上调试,因为要使用android设备的一些硬件功能,所以只能在设备上看效果,否则电脑上很容易跟踪调试)。
原因是当被保人和投保人是同一人时,系统执行了:
this.insured = this.applicant
系统刚开机启动并没有执行上面一句,所以测试是没有问题的,但是当出了一单被保人和投保人是同一人的保单后,上面一句话被执行了,bug就出现了。这样导致这两个对象指向了同一个内容地址。从而造成被保人信息更改会同步更改投保人信息。
解决的方法就是需要明白js中的深拷贝、浅拷贝。
将上面更改成:
this.insured = JSON.parse(JSON.stringify(this.applicant));
问题解决了! 关键是要明白js 中的 深拷贝、浅拷贝。其实在python中也存在这个概念!
记录下问题,让我们少踩点“坑”,所谓坑,其实就是自己的知识盲点!
感谢弟弟与我讨论并提示我注意js中的深拷贝、浅拷贝。