作为javascript开发人员,我们都必须编写很多for循环。在几个月之前,我看到了另一种语法,我非常喜欢。但是,我现在感兴趣,还有其他好方法。
假设我有一个表示系统中用户的数据数组。我之前做的是:
var users = [
{ name: "A"},
{ name: "B"},
{ name: "C"},
{ name: "D"},
{ name: "E"}
];
var numOfUsers = users.length;
for(var i=0; i<numOfUsers; i++) {
var user = users[i];
// ...
}
还有一行var user = users[i];
。通常情况下,如果我有user
而不是users[i]
,我感觉更舒服。所以,新的方式:
for(var i=0; user=users[i]; i++) {
// ...
}
我也想知道第二种方法是否会在某些浏览器中产生问题。我的一位同事报告说,这种语法在IE下有点儿错误。
编辑: 值得庆幸的是,下面的答案向我指出了正确的方向。如果数组的某些元素是假的,那么循环将停止。有某种解决方案:
for(var i=0; typeof (user=users[i]) !== "undefined"; i++) {
// ...
}
但这对我来说太过分了。所以,我想只有当我100%确定所有元素都是真的(这意味着永远不会:)时,我才会使用这种语法。)
答案 0 :(得分:6)
在“新”方法中,您不再需要numOfUsers
。
至于潜在问题:此方法依赖于所有users[i]
评估为true
的值,以便循环继续(user
成为undefined
,等于{ {1}}并且因此在处理完最后一个用户之后结束循环) - 但有时你可能有不的数据,每条记录的评估结果为false
,但“false-y”值可能也出现在数据中 - 在这种情况下,这种方法当然会失败。
答案 1 :(得分:2)
这种方法的问题:
for(var i=0; user=users[i]; i++) {
// ...
}
...假设user
不会“假”(0
,""
,null
,undefined
,{{1 }},或者当然是NaN
),直到你超越了数组的末尾。因此它可以很好地处理一系列非空对象引用,但是如果你习惯使用它,那么当你有一组数字或字符串等时它会咬你。
不在false
构造中声明变量的另一个原因是它具有误导性:那些变量不作用于for
循环,它们在函数范围内。 (JavaScript的for
没有块范围,只有函数或全局范围; ES6将获得具有块范围的var
。)
在现代JavaScript引擎上(或使用“ES5 shim”),您当然可以这样做:
let
...它具有简洁的优点,无需声明users.forEach(function(user) {
// ...
});
或i
或甚至numUsers
(因为它是迭代回调的参数,并且很好地限定了)。如果您担心为每个条目执行函数调用的运行时成本don't be。它会被你在函数中所做的任何实际工作所淹没。
答案 2 :(得分:0)
令我惊讶的是,如果第二种语法适用于所有中间操作,则应在每个要完成的循环中评估为true,并在想要完成循环时立即为false。对于第一个for循环的任何问题,JavaScript都是函数作用域,因此内部var语句仍将泄漏到包含函数(以及i
)。这与大多数其他具有块范围的语言不同。这不是一个问题,但如果您正在调试,请记住一些事项。
答案 3 :(得分:0)
如果您已经在使用jQuery,则可以使用jQuery.each
函数循环遍历数组。
在任何情况下,您都可以查看该函数的源代码并复制自己的foreach
函数的相关部分:http://james.padolsey.com/jquery/#v=1.10.2&fn=jQuery.each