JavaScript中使用splice()无法删除指定数组元素的问题咨询
问题排查与解决方案
嘿,我来帮你理清楚为什么splice()删不掉你指定的数组元素——看你贴的代码片段,主要是几个细节逻辑出了问题,咱们一步步说:
1. 你的inArray函数先踩了坑
你自己写的这个判断值是否在数组里的函数,有两个明显的问题:
- 用
for...in遍历数组:这货是用来遍历对象属性的,不是给数组用的!用它遍历数组会拿到索引的字符串(比如"0"、"1"),还可能意外捞到数组原型链上的额外属性,很容易搞出逻辑错误。 - 错用了
hasOwnProperty:你写的是list.hasOwnProperty(item),但这里遍历的是arr的元素索引,应该判断arr.hasOwnProperty(item)才对——不过其实完全没必要自己写这个函数,数组原生的includes()方法直接就能搞定,简单又靠谱。
比如把inArray换成这个就行:
function inArray(value, arr) { return arr.includes(value); }
要是你非得自己写循环,就用for...of或者普通的for循环,别碰for...in遍历数组。
2. 用splice()删元素的核心:找对索引!
splice()的第一个参数是要删除元素的起始索引,如果索引不对,肯定删不了东西。你可能遇到的情况包括:
- 因为
inArray函数返回错误结果,导致你判断要不要删除时逻辑跑偏; - 正序遍历数组的时候删除元素,删完之后数组长度变短,后面的元素往前挪,导致跳过了某些元素。
给你举个实际的例子,假设你的需求是:把arr中存在于list的id列表里的元素删掉,正确的写法应该是这样:
var arr = [1001, 1002, 1005, 1006]; var list = [{"id": 1002},{"id": 1005},{"id": 1006},{"id": 1007},{"id": 1008},{"id": 1009},{"id": 1010}]; // 先把list里的id都提取成一个数组,方便判断 const listIds = list.map(item => item.id); // 重点:倒序遍历数组!避免删除元素后索引错乱 for (let i = arr.length - 1; i >= 0; i--) { if (listIds.includes(arr[i])) { arr.splice(i, 1); // 从索引i开始,删除1个元素 } } console.log(arr); // 输出 [1001],这就是你要的结果
如果你的需求反过来,是要删掉list里id不在arr中的元素,代码可以这么写:
var arr = [1001, 1002, 1005, 1006]; var list = [{"id": 1002},{"id": 1005},{"id": 1006},{"id": 1007},{"id": 1008},{"id": 1009},{"id": 1010}]; // 同样倒序遍历list,防止索引错乱 for (let i = list.length - 1; i >= 0; i--) { if (!arr.includes(list[i].id)) { list.splice(i, 1); } } console.log(list); // 输出 [{"id":1002},{"id":1005},{"id":1006}]
3. 总结下你原代码的问题根源
inArray函数的遍历方式和属性判断错误,导致值存在性判断失效;- 没注意遍历数组并删除元素时的索引错乱问题,正序遍历会跳过元素;
- 用
for...in遍历数组本身就是个容易踩坑的操作,尽量避开。
内容的提问来源于stack exchange,提问作者mxh861001
相关产品推荐
相关产品推荐

