不知道大家在程式設計的時候有沒有遇到過這種情況,就是在迴圈遍歷刪除一部分內容的時候,發現只能刪除其中一部分,而另一部分卻總也刪不掉,然後覺得自己的邏輯沒有問題啊,於是陷入了深深的抑鬱之中……

昨天在處理一段JS指令碼的時候就遇到了這種問題,業務邏輯很簡單,就是獲取HTML某元素下的所有子元素,然後迴圈刪除(其實更簡單的方法是直接innerHTML賦值為空,這裡只是討論一下關於刪除的問題)。我發現每次刪除完,總是有剩餘,也就是刪不乾淨,於是我進行了除錯,發現當有3個元素時刪除完還剩1個,4個元素剩2個……接著就在利用console.log()在瀏覽器進行打樁,無意中發現返回值竟然是list集合!我是利用children屬性來獲取子元素的,程式碼如下:

var city = document.getElementById("city");

var nodes = city.children;

console.log(nodes);

for(var i = 0; i < nodes.length; i++){

city.removeChild(nodes[i]);

}

以前真心沒有注意過,以為children屬性返回的是陣列。由於JS程式碼過於靈活,全都是var型別來接收,而且獲取長度都是通過length,而不是像java中利用size(),確實不好區分。那麼又開始思考一個問題,為什麼list集合就出錯?

我拿一段簡單的java程式碼舉個例子:

List<String> list = newArrayList<String>();

list.add("cc1");

list.add("cc2");

list.add("cc3");

list.add("cc4");

for (inti = 0; i < list.size(); i++) {

list.remove(i);

}

System.out.println(list);

執行結果是:

[cc2, cc4]

沒錯,有兩個元素沒有刪掉!第一反應是list的長度在變化啊,在不斷減小,就像這個例子,第一次i=0,list長度是4,而第二次i=1,list長度就變成了3,所以根本不會比較4次!於是很自然將程式碼進行修改:

int len =list.size();

for (inti = 0; i < len;i++) {

list.remove(i);

}

卻發現數組越界!!!

這說明了一個問題,就是list的下標發生變化了!當經過思考終於明白,其實當你刪除掉list[0]之後,原來的list[1]變成了現在的list[0],原來的list[2]變成了現在的list[1],所以這麼刪除才會下標越界!

那麼不妨利用while迴圈一直刪除第一項:

while(list.size() > 0){

list.remove(0);

}

這樣結果就對了!迴歸到原來的JS程式碼,發現這樣確實可以解決問題!

而且,你還可以倒著刪除!

總結:

其實這原理很簡單,大家都不難理解,關鍵就是怕有時候大家忽略這一點,一時想不到原因,所以才加以總結。

至少,我有了兩點收穫:

    1. JavaScript中也應該時刻關注一下返回值型別,處理陣列和集合的手段還是不一樣的。

    2. 迴圈刪除集合元素,還是推薦用while,只要一直刪除第一項或者最後一項即可,就像刪除佇列一樣!而且,你還可以倒著刪除!