由一段JS代码引发的思考

不知道大家在编程的时候有没有遇到过这种情况,就是在循环遍历删除一部分内容的时候,发现只能删除其中一部分,而另一部分却总也删不掉,然后觉得自己的逻辑没有问题啊,于是陷入了深深的抑郁之中……

 

昨天在处理一段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=0list长度是4,而第二次i=1list长度就变成了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,只要一直删除第一项或者最后一项即可,就像删除队列一样!而且,你还可以倒着删除!

posted @ 2016-08-17 03:43  DarrenChan陈驰  阅读(234)  评论(0编辑  收藏  举报
Live2D