JavaScript自定义except方法失效原因咨询:结果与预期不符
解析JavaScript except方法的异常原因
问题场景
我编写的首个JavaScript except 方法无法正常工作:调用 except(arr, [2, 4]) 时,预期输出数组 [1, 1, 5, 3],实际得到 [1, 1, 5, 2, 3]。仅当exclude数组的第二个元素在原数组中只出现一次时,该方法能正常运行。我已实现另一个可用的except方法,现解析第一个方法的问题所在。
存在问题的代码
let arr = [1, 2, 1, 4, 5, 4, 2, 3]; function except(arr, exclude) { for (let key in arr) { for (let key1 in exclude) { if (arr[key] === exclude[key1]) { arr.splice(key, 1) } } } console.log(arr) } except(arr, [2, 4]) // expecting [1, 1, 5, 3] // getting [1, 1, 5, 2, 3]
问题核心原因
- 遍历索引时修改原数组导致索引错乱
使用for...in遍历数组索引的同时,调用arr.splice(key, 1)删除元素会直接修改原数组:数组长度缩短,被删除元素后面的所有元素都会向前移位。比如原数组中删除索引1的2后,数组变为[1,1,4,5,4,2,3],但for...in的循环索引会按原序列继续走(下一个索引是2),此时该索引对应的元素是原数组索引3的4,跳过了现在索引1的1,导致后续部分元素未被检查。最终原数组末尾的2因为索引移位,没被循环遍历到,所以没被删除。 - 嵌套循环逻辑存在漏洞
内层循环遍历exclude数组时,即使已经匹配到元素并删除,也没有跳出内层循环,不过这不是主要问题,核心还是修改原数组引发的索引错位。
可用的代码
let arr = [1, 2, 1, 4, 5, 4, 2, 3]; function except(arr, exclude) { let final = []; for (let key of arr) { if (!exclude.includes(key)) final.push(key) } return final; } const output = except(arr, [1, 4]) console.log(output)
可用代码的优势
该版本没有修改原数组,而是创建新数组存储结果。通过for...of遍历原数组的每一个元素,判断元素不在exclude数组内时就加入新数组,彻底避免了修改原数组导致的索引错乱问题,逻辑更简洁,还能保留原数组的完整性。
内容的提问来源于stack exchange,提问作者Deepak Chauhan
相关产品推荐
相关产品推荐

