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

昨天在处理一段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,只要一直删除第一项或者最后一项即可,就像删除队列一样!而且,你还可以倒着删除!

由一段JS代码引发的思考的更多相关文章

  1. 一段奇葩Javascript代码引发的思考

    今天与一挚友加同事调试一段奇葩的javascript代码,在分析出结果后,让我萌生了写此篇文章的想法,如有不对之处望指正,也欢迎大家一起讨论.缩减后的js代码如下,你是否能准确说明他的输出值呢? fu ...

  2. 因一段JavaScript代码引发的闲扯

    前两天,一朋友给我发了一段JavaScript代码: function f1(){ var n=999; nAdd=function(){ n+=1 }; function f2(){ alert(n ...

  3. 一天一小段js代码(no.2)

    (一)可以用下面js代码来检测弹出窗口是否被屏蔽: var blocked = false ; try { /*window.open()方法接受4个参数window.open(要加载的url,窗口目 ...

  4. 我要崩溃了,要解出这么一段js代码背后的东西,这真是一坨啊,别被高度欺骗了,他还有宽度!!!!!试着按下方向右键

    一坨js代码: function s_gi(un, pg, ss) { var c = "s.version='H.26';s.an=s_an;s.logDebug=function(m){ ...

  5. 网页调试js时,如何知道某个事件对应哪段js代码?

    有时候我们需要知道某个事件对应的js代码,比如点击一个div元素时,出现下拉框,我想知道这个功能对应的js代码,那就可以按下图操作: 勾选click事件,重新运行,那么就会在每个click事件那里设置 ...

  6. 一道原生js题目引发的思考(鼠标停留区块计时)

    我瞎逛个啥论坛,发现了一个题目,于是本着练手的心态就开始写起来了,于是各种问题接踵而至,收获不小. 题目是这样的: Demo: mouseenter与mouseover区别demo 跨浏览器的区块计数 ...

  7. 一天一小段js代码(no.4)

    最近在看网上的前端笔试题,借鉴别人的自己来试一下: 题目: 写一段脚本,实现:当页面上任意一个链接被点击的时候,alert出这个链接在页面上的顺序号,如第一个链接则alert(1), 依次类推. 有一 ...

  8. 一天一小段js代码(no.1)

    10000个数字中缺少三个数,编程找出缺少的三个数字. 算法实现: /*生成10000个数中随机抽掉三个数后的数组*/ function supplyRandomArray(){ /*生成含有1000 ...

  9. 一天一小段js代码(no.3)

    //遍历属性,返回名值对 function outputAttributes(element){ var pairs = new Array(), attrName, attrValue, i, le ...

随机推荐

  1. lua upvalue

    转自http://blog.chinaunix.net/uid-52437-id-2108789.html Lua 中的函数是一阶类型值(first-class value),定义函数就象创建普通类型 ...

  2. 基于jquery的消息提示框toastr.js

    //消息提示全局配置 toastr.options = { "closeButton": false,//是否配置关闭按钮 "debug": false,//是 ...

  3. LInux下修改 ~/.bashrc 文件source ~/.bashrc 后 shell 命令 失效 任何命令都显示 “ bash XX :未找到命令”

    原因:在java安装后进行环境变量配置其中 export JAVA_HOME="/opt/java/jdk1.8" export PATH=$JAVA_HOME 即结束 错误原因: ...

  4. asp.net core 日志

    日志输出是应用程序必不可少的部分,log4net,nlog这些成熟的组件在之前的项目中被广泛使用,在asp.net core的项目中没有找到与之对应的log4net版本,nlog对core提供了很好的 ...

  5. datepicker monthpicker

  6. Kafka及 .NET Core 客户端

    消息队列 Kafka 的基本知识及 .NET Core 客户端 消息队列 Kafka 的基本知识及 .NET Core 客户端   前言 最新项目中要用到消息队列来做消息的传输,之所以选着 Kafka ...

  7. NET Core项目定义Item Template

    NET Core项目定义Item Template 作为这个星球上最强大的IDE,Visual Studio不仅仅提供了很多原生的特性,更重要的是它是一个可定制的IDE,比如自定义Project Te ...

  8. MYSQL查询优化

    目前手头有个查询: SELECT LPP.learning_project_pupilID, SL.serviceID, MAX(LPPO.start_date), SUM(LPPOT.license ...

  9. Working Set缓存算法(转)

    为了加深对缓存算法的理解,特转此篇,又由于本文内容过多,故不做翻译,原文地址Working Set页面置换算法 In the purest form of paging, processes are ...

  10. HTML5之CSS3 3D transform 剖析式学习之一

    最近坐地铁发现“亚洲动物基金”在地铁上做了很多公益广告,比较吸引人的是一个月熊的广告.做的很可爱.回去就搜了一下,发现这个网站是HTML5做的,非常炫. 所以想学习一下,方法就是传统的学习办法,模仿. ...