给出的代码是做什么的
它所做的是评估什么contacts[i]
是真实的以及它是否真实,同时缓存适用索引的数组元素。
它等价于下面的代码(注意在这个例子++i
中和 有相同的副作用i++
):
for (var i = 0; contacts[i]; ++i)
{ var contact = contacts[i];
// use contact
}
这可以解释为如下所示:
- 如果
!contacts[i]
是假的(即它是真的)继续循环。
- 否则,结束循环(它是假的)。
如果该代码的目标是遍历整个数组,那么问题将是,如果您想遍历一个元素但它是虚假的,它将结束整个循环而不是执行(可能)预期的效果。举个例子:
var foo = [1, 3, 5, 7, 9, 0, 2, 4, 6, 8];
// example for-loop given
for (var i = 0; foo[i]; ++i)
{ var bar = foo[i];
console.log('example: ' + bar);
}
// "normal" way of iterating through array
for (var i = 0, l = foo.length; i < l; ++i)
{ var bar = foo[i];
console.log('normal: ' + bar);
}
您会发现该示例仅记录到数字 9,而“正常”方式则遍历整个数组。当然,如果您可以保证数组中的所有值都是真实的(例如,所有数组元素都是对象),那么这不是什么大问题。
for-in 有什么作用以及为什么它不起作用
您尝试使用以下代码替换该代码:
for (contact in contacts) { /*code here*/ }
但是,由于多种原因,这不起作用:
contact
是属性名称的字符串,而不是它的值。举个例子:
var foo =
{ bar1: 1
, bar2: 2
, bar3: 3
, bar4: 4
, bar5: 5 };
for (var i in foo) console.log(i);
你得到的是属性名称(即“bar1,bar2...”)而不是值。要对对象执行此操作,您必须执行以下操作:
for (var i in foo)
{ var bar = foo[i];
console.log(bar);
}
现在您应该在不同的行上返回“1,2,3,4,5”。如果你得到了这个,以及其他一些东西,你可能已经定义了项目Object.prototype
- 这就是为什么它通常是一个坏主意,除非它真的使代码更干净,并且这样做有一个实质性的目的。要过滤掉这些,添加一个hasOwnProperty()
检查:
for (var i in foo) if (foo.hasOwnProperty(i))
{ var bar = foo[i];
console.log(bar);
}
即将推出的 ECMAScript 版本(JavaScript 的“标准”版本,减去 DOM)将具有称为 for-of 循环的东西,这将使此类事情变得更容易。
For-in 循环通常不适用于数组(这是可能的,但通常不是一个好主意)。如果您需要使用 for-in,您可能应该改用对象 - 所有数组都是对象,只是数组具有特殊的内部length
属性和其他一些东西。
contact
是一个隐含的全球性的大禁忌。事实上,隐含的全局变量在严格模式下是被禁止的。使用变量声明(在 for-in 循环内部或外部,无关紧要)来解决此问题。
它只是学习 JavaScript 是如何工作的,以及在哪里应用它的各种做事方法——在特定情况下,有些方法比其他方法更合适。