修改对象数组指定索引属性时所有元素同步变更问题排查
问题成因
问题完全出在数组初始化的Array.fill()调用逻辑上:
- 当给
Array.fill()传入引用类型值(对象、数组、函数等)时,该方法不会创建值的独立副本,而是将同一个值的内存引用填充到数组的所有位置。如果传入的是数字、布尔值、字符串这类基本类型,则不会有这个问题,因为基本类型按值存储。 - 你当前初始化的长度为7的数组中,7个元素实际指向内存中完全相同的那一个
{ keepOpen: false }对象实例,并非7个互相独立的对象。 - 因此无论你修改哪个索引位置元素的
keepOpen属性,本质都是修改这个被所有数组项共享的公共对象,最终表现为所有元素的属性同步变化。
修复方案
你的shouldKeepAddToBagOpen方法里的赋值逻辑本身没有问题,不需要调整,只需要修正数组初始化代码,保证数组每个位置存储的是独立创建的对象实例即可,参考写法:
interface productItem { keepOpen: boolean; } // 推荐写法:通过Array.from为每个位置生成独立对象 products$: productItem[] = Array.from({ length: 7 }, () => ({ keepOpen: false })); // 备选写法:fill填充空值后通过map生成新对象 // products$: productItem[] = Array(7).fill(null).map(() => ({ keepOpen: false }));
两种写法的核心逻辑一致:每一次生成对象的逻辑都会执行并返回全新的对象实例,数组各元素的引用互不关联,此时再修改指定index对应元素的属性,就只会作用于目标项,不会影响其他元素。
异常效果参考:
内容的提问来源于stack exchange,提问作者João Pedro
相关产品推荐
相关产品推荐

