JavaScript中的for..in循环

在JS中使用循环,常用两种方式

  1. for(var i=0;i<obj.length;i++){…}
  2. for (var i in obj) {…}

问题复现

在一次使用for..in循环对象时,发现循环次数大于对象的size,从而影响了最终的结果.

<script type="text/javascript">
    $(function () {
        var conferenceSeatUserList = '${conferenceSeatUserList}';
        var seatUser = eval('(' + conferenceSeatUserList + ')');
        for(var i in seatUser){
            var ordinate = seatUser[i].ordinate;
            var abscissa = seatUser[i].abscissa;
            var attendeeName = seatUser[i].attendeeName;
            var obj = $("#tableId")[0].rows[ordinate - 1].cells[abscissa - 1];
            if(seatUser[i].coferenceId!=null){
                obj.innerHTML  = seatUser[i].attendeeName+ '<br/><div class="layui-inline"><button id="updateBtn" class="layui-btn layui-btn-primary layui-btn-pr-master" type="button" onclick="selectAttendeeMan('+seatUser[i].id+')">更改</button>';
            }
            if(seatUser[i].coferenceId==null && seatUser[i].status==2){
                obj.innerHTML  =  '<div class="layui-inline">'+ '<button id="updateBtn" class="layui-btn layui-btn-primary layui-btn-pr-master" type="button" onclick="selectAttendeeMan('+seatUser[i].id+')">选人</button>';
            }
            //启用或禁用座位
            if(seatUser[i].status==2){
                obj.innerHTML  += '<button id="updateBtn" class="layui-btn layui-btn-primary layui-btn-pr-master" type="button" onclick="updateSeatStatus('+seatUser[i].id+',3)">禁用</button>';
            }
            if(seatUser[i].status==3 && seatUser[i].coferenceId==null){
                obj.innerHTML  += '<button id="updateBtn" class="layui-btn layui-btn-primary layui-btn-pr-master" type="button" onclick="updateSeatStatus('+seatUser[i].id+',2)">启用</button>';
            }
        }
    });
</script>

分析原因

查看相关内容发现,for..in循环in判断的是对象的所有属性,包括对象实例及其原型的属性(即会把某个类型的原型(prototype)中方法与属性给遍历出来),所以这可能会导致代码中出现意外的错误.

解决方案

  1. 为了避免这个问题,我们可以使用对象的hasOwnProperty()方法来避免这个问题.
    hasOwnProperty判断一个对象是否有名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。
    如果该属性或者方法是该 对象自身定义的而不是器原型链中定义的 则返回true;否则返回false;
//如果不是该对象自身直接创建的属性(也就是该属性是原型中的属性),则跳过显示
for(var i in seatUser){
    if(!seatUser.hasOwnProperty(i)){
     continue;
    }
    ...
} 
  1. 直接使用for(var i=0;i<obj.length;i++){…},放弃使用for..in循环.

 上一篇
Druid强大的监控和扩展功能 Druid强大的监控和扩展功能
Druid不仅是数据库连接池,还提供强大的监控和扩展功能. Druid监控配置 SSM项目 ①添加Maven依赖<dependency> <groupId>com.alibaba</groupId>
2019-03-11 linhai
下一篇 
Spring Boot项目中使用JSP Spring Boot项目中使用JSP
Spring Boot 的默认视图支持是 Thymeleaf 模板引擎,但是想使用我们熟悉的JSP怎么办? 一.如何配置JSP1. pom.xml中增加对 JSP 文件的支持servlet依赖 <dependency>
2019-03-05 linhai
  目录