在编写脚本时经常用到迭代,比如使用for循环对数组中的所有元素进行迭代:
var list= [1,2,3,4,5]; for(i=0; i<list.length; i++) { alert(list[i]); }
使用这种递增控制法或许效果还不错。另一种可供选择的迭代方法是使用for循环遍历位于(in)list中的每个属性:
var list=[1,2,3,4,5]; for(i in list) { alert(list[i]); }
此时,得到的是与使用前一种迭代方法相同的效果,因为list是一个Array对象。
但是,当使用for(i in item)方法操纵类似数组而又不是数组的对象时一定要格外小心。例如,由getElementsByTagName()返回的NamedNodeMap对象与数组类似而且具有length属性,也就是说可以像对一个常规数组那样对它进行迭代:
var all = document.body.getElementsByTagName("*"); for(i=0; i<all.length; i++) { // 对all[i]元素进行某些操作 }
可是,如果使用下面的迭代方法,那么循环中还将包含NamedNodeMap对象的附加方法:
var all = document.body.getElementsByTagName("*"); for(i in all) { //对all[i]元素进行某些操作 }
在这次的迭代过程中,i的值也会分别等于length、item和namedItem,而这很可能会导致代码中出现意外错误。在某些情况下,可以使用对象的hasOwnProperty()方法来避免这个问题。
如果对象的属性或方法是非继承的,那么hasOwnProperty()方法返回true。即这里的检查不涉及从其他对象继承的属性和方法,只会检查在特定对象自身中直接创建的属性,比如分配给数组的元素。因此,如果在for循环中使用了这种检查,那么循环将会跳过length这样的属性,因为length不是数组all的直系属性,而是从派生数组all的NamedNodeMap对象中继承的属性:
var all = document.body.getElementsByTagName("*"); for(i in all) { if(!all.hasOwnProperty(i)) { continue; } }