(更新:我的其他答案在这里更彻底地列出非 jQuery 选项。下面第三个选项,jQuery.each
,但不在其中。)
四种选择:
通用循环:
var i;
for (i = 0; i < substr.length; ++i) {
// do something with `substr[i]`
}
或者在 ES2015+ 中:
for (let i = 0; i < substr.length; ++i) {
// do something with `substr[i]`
}
优点:直接,不依赖 jQuery,易于理解,不存在保留含义的问题this
在循环体内,没有不必要的函数调用开销(例如,theory更快,尽管事实上你必须有太多的元素,以至于你很可能会遇到其他问题;details).
ES5's forEach
:
从 ECMAScript5 开始,数组有一个forEach
对它们使用函数,这使得循环遍历数组变得容易:
substr.forEach(function(item) {
// do something with `item`
});
链接到文档
(注意:还有很多其他功能,不仅仅是forEach
; see 上面提到的答案了解详情。)
优点:声明式,如果您有一个方便的迭代器,可以使用迭代器的预构建函数,如果您的循环体很复杂,函数调用的范围有时很有用,不需要i
包含范围内的变量。
缺点: 如果你正在使用this
在包含的代码中并且您想要使用this
在你的forEach
回调,你必须 A) 将它放在一个变量中,这样你就可以在函数中使用它,B) 将它作为第二个参数传递给forEach
so forEach
将其设置为this
在回调期间,或 C) 使用 ES2015+箭头函数,结束this
。如果您不执行其中一项操作,则在回调中this
将undefined
(在严格模式下)或全局对象(window
)处于松散模式。曾经有第二个缺点forEach
并未得到普遍支持,但在 2018 年,您将遇到的唯一一个不支持该功能的浏览器forEach
是IE8(而且不可能是properly那里也有聚填充)。
ES2015+ 的for-of
:
for (const s of substr) { // Or `let` if you want to modify it in the loop body
// do something with `s`
}
有关其工作原理的详细信息,请参阅此答案顶部链接的答案。
优点:简单、直接,为数组中的条目提供包含范围变量(或上面的常量)。
缺点:任何版本的 IE 均不支持。
jQuery.each:
jQuery.each(substr, function(index, item) {
// do something with `item` (or `this` is also `item` if you like)
});
(链接到文档)
优点:具有与以下所有相同的优点forEach
,而且您知道它就在那里,因为您使用的是 jQuery。
缺点: 如果你正在使用this
在包含的代码中,您必须将其粘贴在变量中,以便可以在函数中使用它,因为this
表示函数内的其他内容。
您可以避免this
不过,通过使用$.proxy:
jQuery.each(substr, $.proxy(function(index, item) {
// do something with `item` (`this` is the same as it was outside)
}, this));
...or Function#bind
:
jQuery.each(substr, function(index, item) {
// do something with `item` (`this` is the same as it was outside)
}.bind(this));
...或者在 ES2015(“ES6”)中,箭头函数:
jQuery.each(substr, (index, item) => {
// do something with `item` (`this` is the same as it was outside)
});
What NOT to do:
Don't use for..in
为此(或者如果您这样做,请采取适当的保护措施)。你会看到人们这么说(事实上,这里有一个简单的答案这么说),但是for..in
并没有做很多人认为它做的事情(它做了一些更有用的事情!)。具体来说,for..in
循环遍历对象的可枚举属性名称(而不是数组的索引)。由于数组是对象,并且它们唯一的可枚举属性默认情况下是索引,它似乎主要在平淡的部署中工作。但这并不是一个安全的假设,你可以用它来实现这一点。这是一个探索:http://jsbin.com/exohi/3
我应该软化上面的“不要”。如果您正在处理稀疏数组(例如,该数组总共有 15 个元素,但由于某种原因它们的索引分布在 0 到 150,000 的范围内,因此length
是 150,001),and如果您使用适当的保护措施,例如hasOwnProperty
并检查属性名称是否确实是数字(请参阅上面的链接),for..in
可以是避免大量不必要循环的完全合理的方法,因为只会枚举填充的索引。