JS的splice()方法在for迴圈中使用可能會遇到的坑
在寫JS程式碼時,我們常常使用 splice 函式來刪除陣列中的元素,因為 splice 函式會直接對陣列進行修改,從而不需再自己寫一個演算法來移動陣列中的其他元素填補到被刪除的位置。splice 功能十分強大,除了可以刪除陣列的元素之外,還可以刪除的同時新增新的元素到刪除的位置等等用法。在本篇文章中,我只介紹 splice 的刪除陣列元素的用法,和在 for 迴圈中使用 splice 時遇到過的坑,作為記錄以免我下次忘記了這個坑。
在使用 splice 之前,必備條件是,要先有一個數組。。。
看到這個陣列,我覺得中間的數字3不好看,我要把它刪掉。數字3是陣列下標2的元素,而且我只需要刪掉1個數字,於是。。。var arr = new Array(1, 2, 3, 4, 5); //初始化一個數組 [ 1, 2, 3, 4, 5 ]
var index = 2; //數字3在陣列中的下標
var amount = 1; //從陣列的位置index開始刪除數字的個數
var num = arr.splice( index, amount); //從arr陣列的下標2開始刪除一個數字,並將被刪除的數字賦值到num
哇,用 splice 來刪除陣列元素好簡單啊,於是我開開心心地用到 for 迴圈裡面。。。
var arr = new Array(1, 2, 3, 4, 5); //初始化數字集合 var delete_number = 3; //要被刪除的數字 //遍歷陣列 for(var i=0; i<arr.length; i++){ if(arr[i] === delete_number){ //如果找到要被刪除的數字所在的陣列下標 var num = arr.splice( i, 1 ); //從i位置開始刪除1個數字 console.log("成功刪除 "+num); //輸出被刪除的數字 } else{ console.log(arr[i]+" 未被刪除"); //如果i下標的陣列元素不是需要被刪除的數字,就輸出數字 } }
哈哈,討厭的數字3肯定被刪掉了。不過還是要看一下除錯資訊。。。
看見沒有,數字3果然被刪掉了!!!哈哈哈哈,不過仔細一看,咦,4呢???????可愛的數字4沒有被迴圈遍歷到。。。
前面說過,splice 是直接操作並修改陣列的,所以當找到數字3時在迴圈中的 i 下標是2,而當刪除數字3後,陣列下標 i 位置中儲存的數字變為了數字4,然後到了下一個迴圈 i 下標為3時,陣列下標 i 位置中儲存的數字是5,所以跳過了數字4,於是除錯資訊中沒有可愛的數字4.。。。原理就是這樣子,是不是很繞。
題外話:因為我的疏忽,在一個for迴圈中加入了 splice 後,導致了我的H5遊戲專案中的眾多 NPC 中的某一個 NPC 並沒有按預期地移動到相應的位置。最重要的是我還提交到了版本庫,與 splice 同時提交了幾百行程式碼,所以不能回退版本只能斷點除錯到深夜才找到這麼小小錯誤。所以我寫了這篇文章來記錄一下在 for 迴圈中使用 splice 的坑。
說了這麼多,怎麼解決漏掉了數字4這個問題呢???很簡單,在使用 splice 的下一句,改一下迴圈變數值即可。。。
if(arr[i] === delete_number){ //如果找到要被刪除的數字所在的陣列下標
var num = arr.splice( i, 1 ); //從i位置開始刪除1個數字
console.log("成功刪除 "+num); //輸出被刪除的數字
i = i-1; //解決方案
}
看完以上內容,是不是覺得特別簡單而且小菜一碟,粗都嘛爹,等一下,我要確保你不會向我一樣犯 splice 引起的低階錯誤,所以請看以下程式碼,比以上的稍微複雜一點點,如果你僅根據程式碼推出的答案跟結果一樣,就能確保下次使用 splice 時會有意識避開問題了。。。
var arr = new Array(1, 2, 3, 4, 5); //初始化數字集合
var delete_number = 3; //要被刪除的數字
var amount = 2; ////從陣列的某位置開始刪除數字的個數
var loop = arr.length; //迴圈次數
//遍歷陣列
for(var i=0; i < loop; i++){
if(arr[i] === delete_number){ //如果找到要被刪除的數字所在的陣列下標
var num = arr.splice( i, amount ); //從i位置開始刪除1個數字
i = i - 1; //改變迴圈變數
loop = loop - amount; //改變迴圈次數
}
else{
console.log( arr[i] + ", ");
}
}
//結果:1,2,5