for循环中使用splice未移除指定索引,页面重载后结果异常
问题:splice移除指定索引后结果不符合预期
页面重载后,splice方法处理后的数组结果为[0:{"title":"C"}],而非预期的[0:{"title":"B"}]
初始存储数据
// 存储在localStorage中的todos todos = [{"title":"A"}, {"title":"B"}, {"title":"C"}] // 存储在localStorage中的待移除元素索引(需要删除A和C) deletedTodo = [0,2]
页面加载逻辑
window.addEventListener("load", (e) => { todos = JSON.parse(localStorage.getItem("todos")) || []; clearTodo(); });
处理删除逻辑的函数
以下函数用于检查需从todos中移除的已删除索引,返回更新后的todos对象;否则返回displayTodos()
function clearTodo() { if ( JSON.parse(localStorage.getItem("deletedTodo")) && JSON.parse(localStorage.getItem("deletedTodo")).length > 0 ) { for ( let index = 0; index <= JSON.parse(localStorage.getItem("deletedTodo")).length; index++ ) { todos.splice(JSON.parse(localStorage.getItem("deletedTodo"))[index], 1); } localStorage.setItem("todos", JSON.stringify(todos)); localStorage.setItem("deletedTodo", JSON.stringify([])); deletedIndexex = []; return displayTodos(); } else { return displayTodos(); } }
问题原因分析
- 循环条件错误:循环使用
index <= deletedTodo.length,当deletedTodo长度为2时,index会取0、1、2,最后一次循环取到的索引是undefined,执行splice(undefined,1)会删除数组最后一个元素,属于多余的错误操作。 - 数组索引偏移问题:正序删除元素时,删除索引0的元素后,原数组长度变为2,原索引2的元素会变成索引1,此时再去删除索引2的元素,无法命中目标;结合循环条件错误,最终导致最后一个元素被误删。
- 重复解析localStorage:循环中多次调用
JSON.parse(localStorage.getItem("deletedTodo")),既影响性能,也增加了代码出错风险。
解决方案
修改clearTodo函数,做以下优化:
- 先把deletedTodo从localStorage取出并解析,存到变量中,避免重复操作
- 倒序遍历删除索引,这样删除大索引的元素不会影响小索引的位置
- 修正循环条件为
index < deletedTodo.length
修改后的代码:
function clearTodo() { const deletedTodo = JSON.parse(localStorage.getItem("deletedTodo")) || []; if (deletedTodo.length > 0) { // 倒序遍历,避免索引偏移 for (let index = deletedTodo.length - 1; index >= 0; index--) { const todoIndex = deletedTodo[index]; todos.splice(todoIndex, 1); } localStorage.setItem("todos", JSON.stringify(todos)); localStorage.setItem("deletedTodo", JSON.stringify([])); deletedIndexex = []; return displayTodos(); } else { return displayTodos(); } }
这样处理后,先删除索引2的元素(C),再删除索引0的元素(A),最终todos会剩下[{"title":"B"}],符合预期。
内容的提问来源于stack exchange,提问作者FAHAD
相关产品推荐
相关产品推荐

