You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题原因分析

  1. 循环条件错误:循环使用index <= deletedTodo.length,当deletedTodo长度为2时,index会取0、1、2,最后一次循环取到的索引是undefined,执行splice(undefined,1)会删除数组最后一个元素,属于多余的错误操作。
  2. 数组索引偏移问题:正序删除元素时,删除索引0的元素后,原数组长度变为2,原索引2的元素会变成索引1,此时再去删除索引2的元素,无法命中目标;结合循环条件错误,最终导致最后一个元素被误删。
  3. 重复解析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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 06:22:27