使用array.splice操作数组时遭遇无限循环问题求助
数组插入元素触发无限循环问题
问题代码
for (let i = 0; i < waypoints.length; i++) { if(waypoints[i].id.toString() === data.waypoint.waypoint.toString()) { if(data.waypoint.where.toString() === 'above') { waypoints.splice(i, 0, waypoint) } if(data.waypoint.where.toString() === 'below') { waypoints.splice(i+1, 0, waypoint) } if(data.waypoint.where.toString() === 'none') { waypoints.push(waypoint) } } }
问题描述
我有一个名为waypoints的对象数组,每个对象都包含id属性。前端展示该数组的列表,每个对象配有“添加到上方”和“添加到下方”按钮。其中“none”对应的逻辑运行正常,但触发“above”或“below”逻辑时会陷入无限循环。我需要找到对应id的waypoint并按指定位置插入元素,目前无法解决该问题,此前相关帖子的方案也不清晰。
问题原因
循环过程中用splice插入元素会直接增加数组长度。比如触发“above”逻辑时,新元素插在索引i的位置,原本的目标元素会被挤到i+1的位置。下一次循环i递增1,又会匹配到这个被挤后的目标元素,再次执行插入操作,数组长度持续增加,i永远追不上新的数组长度,最终陷入无限循环。
解决方案
方案一:找到目标后立即终止循环
在插入完成后直接break退出循环,避免重复匹配:
for (let i = 0; i < waypoints.length; i++) { if(waypoints[i].id.toString() === data.waypoint.waypoint.toString()) { const where = data.waypoint.where.toString(); if (where === 'above') { waypoints.splice(i, 0, waypoint); } else if (where === 'below') { waypoints.splice(i+1, 0, waypoint); } else if (where === 'none') { waypoints.push(waypoint); } // 找到目标后直接跳出循环,防止重复处理 break; } }
方案二:先查找索引再插入
把查找目标索引和插入操作分开,彻底避免循环中修改数组的问题:
// 先找到目标元素的索引 const targetIndex = waypoints.findIndex(item => item.id.toString() === data.waypoint.waypoint.toString() ); // 找到索引后再执行插入逻辑 if (targetIndex !== -1) { const where = data.waypoint.where.toString(); switch(where) { case 'above': waypoints.splice(targetIndex, 0, waypoint); break; case 'below': waypoints.splice(targetIndex + 1, 0, waypoint); break; case 'none': waypoints.push(waypoint); break; } }
说明
两种方案都能解决无限循环问题:方案一在循环内处理但及时终止,适合简单场景;方案二逻辑分离,代码更清晰易维护,推荐使用。
内容的提问来源于stack exchange,提问作者Calin Onaca
相关产品推荐
相关产品推荐

