背景
遇到一个很诡异的bug,地域树中子集的最前面加上全部选项,最后一颗树永远遍历不到
const Regions = [
// 此处添加 { name: '全部' }
{
id: 111,
name: "杭州市",
children: [
// 此处添加 { name: '全部' }
{
id: 1110,
name: "萧山区",
children: null,
},
{
id: 1111,
name: "余杭区",
children: null
}
]
},
{
id: 222,
name: "湖州市",
children: [
// 此处添加 { name: '全部' }
{
id: 2220,
name: "s区",
children: null
},
{
id: 2221,
name: "p区",
children: null
}
]
}
];
简单demo
普通遍历打印:
Regions.forEach((region, index) => {
console.log(region.name, index);
region.children.forEach((child, idx) => {
console.log(child.name, idx);
});
});
结果:

修改原数组遍历打印:
Regions.forEach((region, index) => {
Regions.unshift({ name: "市全部" });
console.log(region.name, index);
region.children.forEach((child, idx) => {
region.children.unshift({ name: "镇全部" });
console.log(child.name, idx);
});
});
结果:

分析
这不明显遍历原数组不对,结果完全不一样了, forEach添加自身元素index不会被重置,会隐性让index自增,for offorEach循环操作原数组得出返回后的原数组都不准确。
结论
不要再for循环中操作原数组(长度相关)!!!
不要再for循环中操作原数组(长度相关)!!!
不要再for循环中操作原数组(长度相关)!!!
重要的事情说三次
解决方案
若非要操作,通过延迟操作可解急眉如:
Regions.forEach((region, index) => {
let timer = setTimeout(() => {
Regions.unshift({ name: "市全部" });
clearTimeout(timer);
});
console.log(region.name, index);
region.children.forEach((child, idx) => {
let timer = setTimeout(() => {
region.children.unshift({ name: "镇全部" });
clearTimeout(timer);
});
console.log(child.name, idx);
});
});
文章讨论了一个在遍历地域树结构时遇到的bug,当在子集最前面添加全部选项后,使用forEach遍历最后一层时出现问题。原因是forEach在循环中修改原数组导致索引混乱。作者强调了在for循环中不应直接操作长度相关的原数组,并提供了解决方案,即通过异步操作(setTimeout)来延迟修改,以避免影响遍历过程。
676

被折叠的 条评论
为什么被折叠?



