陣列遍歷過程中改變陣列長度而引起的錯誤
阿新 • • 發佈:2020-12-30
陣列遍歷過程中增刪元素的後果
1、先說結論:
在用for迴圈、物件方法(forEach()、map()等)對陣列進行遍歷操作時,儘量不要改變原陣列的長度(增、刪元素),否則非常容易出錯。
2、例子:
// 目的:列印陣列中每個元素,並刪除陣列中值為1的元素
let arr = [1,2,3];
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
if (arr[i] == 1) {
arr.splice(i, 1);
console.log(arr);
}
}
輸出結果為:
1
[2,3]
3
容易誤認為應該列印
1
2
[2,3]
3
這是因為在刪除arr[0],即值為1的元素以後,
原來的第二個元素2,變成了第一個元素即arr[0];原來的第三個元素3,變成了第二個元素即arr[1],
陣列的長度變為2,而此時i=0,則下一個arr[i]為為arr[1]即值為3的元素。
值為2的元素因為變成了arr[0],所以被直接跳過。
所以如果在遍歷原陣列的過程中刪掉了一個元素,那麼這個元素的下一個元素就不會被遍歷到。
//第一個迴圈 { i = 0; console.log(arr[i]); // 列印arr[0] = 1 arr.splice(0,1); //arr[0],即值為1的元素被移除 console.log(arr); //arr = [2,3] } //第二個迴圈,此時原來的第二個元素2,變成了第一個元素arr[0];原來的第三個元素3,變成了第二個元素arr[1],陣列的長度變為2 { i = 1; console.log(arr[i]); // 列印arr[1] = 3 } //第三個迴圈 { i = 2; // i < arr.length為false,不執行 }
3、陣列中增刪元素的正確做法:
正確的思路應該是深拷貝一個新陣列,對新陣列進行增刪操作。
如在例子中,用slice()而不是splice()。