
本文介绍一种安全、可读性强的方案,使用反向遍历配合状态缓存,将对象中值为空数组的键,用其后首个非空数组的第一个元素填充(深拷贝),避免原逻辑中的索引越界与引用污染问题。
在处理配置对象或数据映射结构时,常需对缺失值进行“向后填充”(forward-fill from next non-empty)——即:当某个 key 对应的 value 是空数组 [] 时,将其填充为之后第一个非空数组的首项(而非简单取 index + 1 处的值,因后续可能仍为空)。原始尝试存在明显缺陷:
- 直接访问 values[index+1][1][0] 易引发 undefined 访问错误;
- 未处理连续多个空数组的情况;
- 修改原对象时未做深拷贝,导致引用共享风险。
✅ 推荐解法:反向遍历 + 状态缓存(next)
核心思想是:从最后一个属性开始向前扫描,维护一个变量 next,记录最近遇到的合法首元素。一旦遇到空数组,就用当前 next 填充;若遇到非空数组,则更新 next 为该数组首项(并确保深拷贝):
const myItems = {
'items1': [{first: true, second: false}, {first: true, second: true}],
'items2': [],
'items3': [],
'items4': [{first: true, second: false}, {first: true, second: true}],
'items5': [{first: false, second: true}],
'items6': [],
'items7': [{first: true, second: true}],
};
let next = null;
// 反向遍历 values,确保“后续”逻辑自然成立
Object.values(myItems).reverse().forEach(arr => {
if (Array.isArray(arr) && arr.length > 0) {
// 更新 next 为当前非空数组的首元素(深拷贝)
next = { ...arr[0] };
} else if (Array.isArray(arr) && arr.length === 0 && next !== null) {
// 填充空数组:赋值为深拷贝后的 next
arr.push({ ...next });
}
});
console.log(myItems);
// items2/items3 → [{first:true, second:false}]
// items6 → [{first:true, second:true}]⚠️ 关键注意事项:
- 必须使用 reverse().forEach() 或 reduceRight():正向遍历无法保证“下一个非空”在逻辑上已处理过;反向则天然满足“已知后续最优候选”的前提。
- 深拷贝不可省略:直接赋 arr[0] = next 会导致所有空数组引用同一对象,修改一处将影响全部。{...next} 是最简安全深拷贝(适用于浅层对象);如需深层嵌套支持,请改用 structuredClone(next)(现代环境)或 JSON.parse(JSON.stringify(next))(兼容性方案)。
- 健壮性增强建议:可在填充前增加类型校验(如 if (!Array.isArray(arr)) return;),避免意外传入非数组值导致运行时错误。
此方案时间复杂度 O(n),空间复杂度 O(1),逻辑清晰、易于测试与维护,是处理此类“向后填充空数组”场景的推荐实践。










