动态创建的JavaScript对象未按预期填充问题排查
问题分析与解决方案
你遇到的问题核心是JavaScript对象/数组的引用传递特性导致的,我来帮你拆解清楚:
问题根源
你动态创建target时,所有day对应的data都复用了同一个intervalObj数组的引用。也就是说,target[0].data和target[1].data指向的是内存中的同一个数组对象。当你在后续填充数据时,修改其中一个的number值,其他所有复用这个引用的data都会同步变化,这就导致了求和结果在所有星期几中重复的问题。
而静态创建target时,每个day的data都是独立声明的新数组,彼此没有引用关联,所以修改各自的number不会互相影响。
修复方案
解决思路很简单:为每个day生成独立的intervalObj副本,而不是复用同一个引用。可以用Array.map()方法来快速生成新的对象数组,代码修改如下:
var res = [{ DateTime: '00:00', Number: 1, WeekDay: 1 }, { DateTime: '00:00', Number: 4, WeekDay: 1 }, { DateTime: '00:00', Number: 1, WeekDay: 2 }, { DateTime: '00:30', Number: 1, WeekDay: 2 }]; var intervals = ['00:00', '00:30'] var weekdays = [1, 2] var target = [] // 不再提前创建全局的intervalObj,而是在循环中为每个日期生成独立的数组 for (i = 0; i < weekdays.length; i++) { var day = i + 1; // 用map生成新的对象,每个对象都是独立的引用 var dayIntervalData = intervals.map(interval => ({ interval: interval, number: 0 })); target.push({ day: day, data: dayIntervalData }) } // 后续填充数据的代码保持不变 for(var row in res) { var dt = res[row].DateTime; var wd = res[row].WeekDay; var wdidx = weekdays.indexOf(wd) var dtidx = intervals.indexOf(dt) var num = res[row].Number; target[wdidx].data[dtidx].number += num; }
这样修改后,每个day的data都是完全独立的数组对象,后续的求和操作就只会影响对应星期几的对应时间间隔,不会再出现结果重复的问题了。
补充说明
如果你的intervalObj结构更复杂(比如嵌套对象),可能需要用到深拷贝,但在这个场景下,因为每个元素都是简单的键值对对象,用map生成新对象的浅拷贝方式就足够了。
内容的提问来源于stack exchange,提问作者oceansmoving
相关产品推荐
相关产品推荐

