我正在编辑Chrome的示例oauth contacts extension
当我在contacts.js
第7行遇到一个有趣的for循环时:
for (var i = 0, contact; contact = contacts[i]; i++) {
变量i
从未在for循环的主体中使用,所以它看起来像是一个典型的“for ... in”循环。我尝试用
for (contact in contacts) {
但是当我运行扩展程序时,我的所有联系人都回来了undefined
这是扩展名
的完整for循环for (var i = 0, contact; contact = contacts[i]; i++) {
var div = document.createElement('div');
var pName = document.createElement('p');
var ulEmails = document.createElement('ul');
pName.innerText = contact['name'];
div.appendChild(pName);
for (var j = 0, email; email = contact['emails'][j]; j++) {
var liEmail = document.createElement('li');
liEmail.innerText = email;
ulEmails.appendChild(liEmail);
}
div.appendChild(ulEmails);
output.appendChild(div);
}
答案 0 :(得分:3)
它的作用是评估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 (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
是一个隐含的全球性,大禁忌。事实上,暗示全局are banned in strict mode。使用变量声明(在for-in循环内部或外部,无关紧要)来解决此问题。
它只是学习JavaScript如何工作以及在何处应用其各种处理方法 - 在特定情况下,某些方法比其他方法更合适。
答案 1 :(得分:2)
这里使用的是数组,而不是对象。
虽然使用for..in输出与普通for循环相同的结果,但这将是我的答案。
<强> MyRecommendation 强>:
使用
for..in
迭代对象:
for..in迭代对象的属性。
注意:迭代的顺序是任意的。
var Myobj = {
a: 1,
b: 2,
c: 3
};
for ( var prop in Myobj ) {
console.log(prop); // a...b...c
console.log(Myobj[prop]); // 1...2...3
}
但问题是它会继续在原型链上搜索可枚举的属性。除非你不使用hasOwnProperty
,否则它将遍历本地对象及其附加的原型。
//Improved version of above code:
for (var prop in Myobj) {
if ( Myobj.hasOwnProperty(prop) ) {
// prop is actually obj's property (not inherited)
console.log(prop); // a...b...c
console.log(Myobj[prop]); // 1...2...3
}
}
使用
for loop
进行数组迭代
for循环以顺序方式迭代数组。