循环中操作原数组的后果(长度变化)

背景

遇到一个很诡异的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);
    });
  });

猜你喜欢

转载自blog.csdn.net/SwingDance/article/details/129316562