【js】记录深拷贝一个Array或Object但不生效的原因和解决方法

14 篇文章 0 订阅

背景:使用JSON.parse(JSON.stringify)或lodash的_.cloneDeep方法深拷贝一个Array数据constantForm,又利用constantForm创建了一个新数据showForm,在改变showForm时,拷贝的数据constantForm也会随着一起变

原因:因为constantForm的对象属性也存在引用类型(对象或数组),这些属性在constantForm创建后又被修改(比如直接修改了某个对象或数组的内部状态),这种修改可能会影响showForm的表现。因为showForm中持有对某个对象的引用(比如defaultValue),而这个对象在constantForm中也被引用。filter方法返回一个新数组,其中包含的是原数组中符合条件的元素的浅拷贝(即数组是新的,但是数组中的对象引用仍然是相同的)

代码示例:

data() {
	const defaultValue = {
		one: '默认值1',
		two: '默认值2',
	}
	const listArr = {
		list1: [
			...
		],
		list2: [
			...
		],
	}
	const defaultForm = [
		{
			type: 'checkbox',
			value: defaultValue.one,
			list: listArr.list1,
		},
		{
			type: 'radio',
			value: defaultValue.two,
			list: listArr.list2,
		},
	]
	return {
		constantForm: JSON.parse(JSON.stringify(defaultForm)),
	}
},
methods: {
	edit() {
		this.showForm =  this.constantForm.filter(item => item.kind===fundTypeMap.common || value.includes(item.kind))
	}
}

解决方法:对数组中的每个对象进行深拷贝

	edit() {
		// JSON.parse(JSON.stringify())效率较低,因为对每个对象都进行了序列化和反序列化
		this.showForm =  this.constantForm.map(item => JSON.parse(JSON.stringify(item))).filter(item => item.kind===fundTypeMap.common || value.includes(item.kind))
		// 可以使用lodash的cloneDeep,这种方法更灵活,可以处理更多类型的数据
		this.showForm =  this.constantForm.map(item => _.cloneDeep(item)).filter(item => item.kind===fundTypeMap.common || value.includes(item.kind))
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值