Consequences of operating the original array in the loop (length change)

background

Encountered a very weird bug, adding all options to the front of the subset in the region tree, the last tree will never be traversed

   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
        }
      ]
    }
  ];

simple demo

Ordinary traversal prints:

  Regions.forEach((region, index) => {
    
    
    console.log(region.name, index);
    region.children.forEach((child, idx) => {
    
    
      console.log(child.name, idx);
    });
  });

result:
insert image description here

Modify the original array to traverse and print:

  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);
    });
  });

result:
insert image description here

analyze

It is not obvious that it is wrong to traverse the original array, and the result is completely different. The index of forEach adding its own elements will not be reset, and the index will be implicitly incremented.

in conclusion

Do not operate the original array (length dependent) in the for loop! ! !
Do not operate the original array (length dependent) in the for loop! ! !
Do not operate the original array (length dependent) in the for loop! ! !
important things said three times

solution

If you have to operate, you can solve the problem by delaying the operation, such as:

  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);
    });
  });

Guess you like

Origin blog.csdn.net/SwingDance/article/details/129316562