JavaScript数组对象转换异常:结果重复最后索引数据
数组对象转换时出现重复数据的问题分析与解决
问题描述
将数组对象转换为指定格式时,输出结构符合预期,但新数组的每个索引位置都被最后一个索引的对象覆盖,所有元素都是重复的最后一组数据。
输入数据
let data = [ { 0: { value1: true, value2: false, isSelected: false, }, 1: { value1: true, value2: true, isSelected: true, }, 2: { value1: false, value2: false, isSelected: false, }, 3: { value1: false, value2: false, isSelected: false, }, 4: { value1: true, value2: true, isSelected: true, }, Stage: 'A', }, { 0: { value1: false, value2: false, isSelected: false, }, 1: { value1: true, value2: true, isSelected: true, }, 2: { value1: false, value2: false, isSelected: false, }, 3: { value1: false, value2: false, isSelected: false, }, 4: { value1: true, value2: true, isSelected: true, }, Stage: 'B', }, { 0: { value1: false, value2: false, isSelected: false, }, 1: { value1: true, value2: true, isSelected: true, }, 2: { value1: false, value2: false, isSelected: false, }, 3: { value1: false, value2: false, isSelected: false, }, 4: { value1: true, value2: true, isSelected: true, }, Stage: 'C', }, ];
预期输出
// 预期输出数据 [ { Stage: [ { value1: true, value2: false, isSelected: false, }, { value1: true, value2: true, isSelected: true, }, { value1: false, value2: false, isSelected: false, }, { value1: false, value2: false, isSelected: false, }, { value1: true, value2: true, isSelected: true, }, ], }, { Stage: [ { value1: false, value2: false, isSelected: false, }, { value1: true, value2: true, isSelected: true, }, { value1: false, value2: false, isSelected: false, }, { value1: false, value2: false, isSelected: false, }, { value1: true, value2: true, isSelected: true, }, ], }, { Stage: [ { value1: false, value2: false, isSelected: false, }, { value1: true, value2: true, isSelected: true, }, { value1: false, value2: false, isSelected: false, }, { value1: false, value2: false, isSelected: false, }, { value1: true, value2: true, isSelected: true, }, ], }, ];
尝试的代码
stagesBackTransform = (data) => { let newArr = new Array(data.length).fill({ Stage: new Array(16) }); data.forEach((stage, stageIdx) => { Object.entries(stage).forEach((item, idx) => { if (item[0] !== 'Stage') { // newArr[stageIdx].Stage[item[0]] = item[1]; newArr[stageIdx].Stage[idx] = item[1]; } }); }); console.log('new:', newArr); return newArr; };
运行代码片段
let data = [ { 0: { value1: true, value2: false, isSelected: false }, 1: { value1: true, value2: true, isSelected: true }, 2: { value1: false, value2: false, isSelected: false }, 3: { value1: false, value2: false, isSelected: false }, 4: { value1: true, value2: true, isSelected: true }, Stage: 'A', }, { 0: { value1: false, value2: false, isSelected: false }, 1: { value1: true, value2: true, isSelected: true }, 2: { value1: false, value2: false, isSelected: false }, 3: { value1: false, value2: false, isSelected: false }, 4: { value1: true, value2: true, isSelected: true }, Stage: 'B', }, { 0: { value1: false, value2: false, isSelected: false }, 1: { value1: true, value2: true, isSelected: true }, 2: { value1: false, value2: false, isSelected: false }, 3: { value1: false, value2: false, isSelected: false }, 4: { value1: true, value2: true, isSelected: true }, Stage: 'C', }, ]; stagesBackTransform = (data) => { let newArr = new Array(data.length).fill({ Stage: new Array(16) }); data.forEach((stage, stageIdx) => { Object.entries(stage).forEach((item, idx) => { if (item[0] !== 'Stage') { // newArr[stageIdx].Stage[item[0]] = item[1]; newArr[stageIdx].Stage[idx] = item[1]; } }); }); console.log('new:', newArr); return newArr; }; const result = stagesBackTransform(data); console.log(result);
错误原因
问题出在创建newArr的这一行:
let newArr = new Array(data.length).fill({ Stage: new Array(16) });
Array.fill()方法会将同一个对象引用填充到数组的所有位置。也就是说,newArr里的每一个元素都指向同一个{ Stage: [...] }对象。后续循环中修改任意索引的Stage数组时,都是在修改这个共享的对象,最终所有元素都会显示最后一次修改的结果,导致数据重复。
修正后的代码
改用Array.from()创建独立的对象,确保每个数组元素都是全新的对象引用:
stagesBackTransform = (data) => { // 用Array.from创建每个独立的对象,避免引用共享 let newArr = Array.from({ length: data.length }, () => ({ Stage: new Array(16) })); data.forEach((stage, stageIdx) => { // 先过滤掉'Stage'键,再按数字排序确保顺序正确 Object.keys(stage) .filter(key => key !== 'Stage') .sort((a, b) => Number(a) - Number(b)) .forEach((key, idx) => { newArr[stageIdx].Stage[idx] = stage[key]; }); }); console.log('new:', newArr); return newArr; };
另外,这里增加了对数字键的排序处理,避免Object.keys()返回的键顺序不稳定导致的赋值错误,让转换结果更可靠。
内容的提问来源于stack exchange,提问作者Alpesh Nakrani
相关产品推荐
相关产品推荐

