当我尝试使用通过循环的方法从数组中删除所有元素时splice
,我得到以下信息:
const arr = [1, 2, 0, 3, 0, 0, 0, 3, 4, 5, 7];
for (let i = 0; i < arr.length; i++) {
arr.splice(i, 1);
console.log(arr, i)
}
console.log(arr); // [2, 3, 0, 3, 5]
该代码删除每隔一个元素,并且按照设计应该留下一个空数组。
另一个例子:
const arr = [1, 2, 0, 3, 0, 0, 0, 3, 4, 5, 7];
for (const elem of arr) {
arr.splice(elem, 1);
console.log(arr, elem);
}
console.log(arr); // [0, 0, 0, 3, 5, 7]
这里的结果很奇怪。好像方法本身决定了删除什么,不删除什么。
错误在哪里?
主要是你的逻辑错误。根据它,在第一种和第二种情况下,您访问数组就好像它没有被更改一样,但事实并非如此。您删除元素
在第一种情况下,每次删除都会增加索引,你似乎跳过了元素,因为删除时,索引也减少了 1,而i增加了 1。
在第二种情况下,您传递的第一个元素不是索引,而是元素的值——当然,在这里,一切都不会那么明显。
因此,很容易平衡情况:
但这并没有按预期清除两个数组,因为数组是突变的。在
for
,for of
并且for in
数组长度的值没有正确计算的情况下,请注意0, 3, 4, 5, 7
- 这些是数组中的最后一个数字,它只是没有到达它们,因为在条件i < arr.length
i和arr中。长度彼此靠近并大约停在中间,例如:5 < 5while
但是当它每次收到数组的实际长度并且退出条件已经符合预期时,就不会发生这种情况,即while
允许被集成对象的任何突变,但应尽可能避免。