在JS中使用循环,常用两种方式
- for(var i=0;i<obj.length;i++){…}
- 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)中方法与属性给遍历出来),所以这可能会导致代码中出现意外的错误.
解决方案
- 为了避免这个问题,我们可以使用对象的hasOwnProperty()方法来避免这个问题.
hasOwnProperty判断一个对象是否有名称的属性或对象,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。
如果该属性或者方法是该 对象自身定义的而不是器原型链中定义的 则返回true;否则返回false;
//如果不是该对象自身直接创建的属性(也就是该属性是原型中的属性),则跳过显示
for(var i in seatUser){
if(!seatUser.hasOwnProperty(i)){
continue;
}
...
}
- 直接使用for(var i=0;i<obj.length;i++){…},放弃使用for..in循环.