修复LocalStorage数组删除对象时的异常(非首元素删除出错)
问题根源分析
你的问题出在用forEach遍历数组时直接调用splice修改原数组,这会破坏遍历的索引逻辑,导致意外的删除行为。
当你在forEach中删除元素时,数组的长度和元素位置会立即改变:
- 删除第一个元素时,数组后续元素前移,但
forEach的下一次迭代索引会正常推进,刚好遍历到新的第一个元素,所以看起来正常。 - 删除第二个或其他位置的元素时,数组元素前移后,
forEach的索引不会自动调整,导致后续遍历跳过部分元素,甚至因为索引错位错误地删除更多元素,最终出现"保留第一个、删除其余"的异常。
另外,data.indexOf(note)也存在隐患:如果数组中有多个内容相同的note对象,indexOf只会返回第一个匹配的索引,可能导致删除错误的元素。
修复方案
推荐两种更安全的写法:
方案1:使用filter生成新数组(最优)
filter不会修改原数组,而是返回符合条件的新数组,逻辑清晰且避免索引问题:
const deleteNote = (event) => { // 读取本地存储,为空时默认空数组 const notes = JSON.parse(localStorage.getItem("notes")) || []; // 过滤掉需要删除的元素 const updatedNotes = notes.filter(note => note.note !== event.value); // 更新本地存储 localStorage.setItem("notes", JSON.stringify(updatedNotes)); // 删除DOM元素 event.parentElement.remove(); };
这种写法更符合函数式编程思想,代码简洁易维护,还能避免遍历过程中修改数组的风险。
方案2:倒序for循环遍历
如果一定要修改原数组,用倒序for循环可以避免索引错位:
const deleteNote = (event) => { let data = JSON.parse(localStorage.getItem("notes")) || []; // 从最后一个元素开始遍历,删除元素不影响前面的索引 for (let i = data.length - 1; i >= 0; i--) { if (data[i].note === event.value) { data.splice(i, 1); // 只删除第一个匹配项,找到后直接跳出循环 break; } } localStorage.setItem("notes", JSON.stringify(data)); event.parentElement.remove(); };
倒序遍历的好处是:删除当前元素后,前面未遍历的元素索引不会受到影响,不会出现跳过或错误删除的情况。
内容的提问来源于stack exchange,提问作者Rod021
相关产品推荐
相关产品推荐

