在 JavaScript 中循环遍历数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3010840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Loop through an array in JavaScript
提问by Mark Szymanski
In Java you can use a forloop to traverse objects in an array as follows:
在 Java 中,您可以使用for循环来遍历数组中的对象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
// Do something
}
Can you do the same in JavaScript?
你能用 JavaScript 做同样的事情吗?
回答by CMS
You have several options:
您有多种选择:
1. Sequential forloop:
1. 顺序for循环:
var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
console.log(myStringArray[i]);
//Do something
}
Pros
优点
- Works on every environment
- You can use
breakandcontinueflow control statements
- 适用于各种环境
- 您可以使用
break和continue流量控制语句
Cons
缺点
- Too verbose
- Imperative
- Easy to have off-by-one errors(sometimes also called a fence post error)
- 太冗长
- 至关重要的
- 容易出现一对一错误(有时也称为栅栏柱错误)
2. Array.prototype.forEach
2. Array.prototype.forEach
The ES5 specification introduced a lot of beneficial array methods, one of them, the Array.prototype.forEachand it gives us a concise way to iterate over an array:
ES5 规范引入了许多有益的数组方法,其中之一,Array.prototype.forEach它为我们提供了一种迭代数组的简洁方法:
const array = ["one", "two", "three"]
array.forEach(function (item, index) {
console.log(item, index);
});
Being almost ten years as the time of writing that the ES5 specification was released (Dec. 2009), it has been implemented by nearly all modern engines in the desktop, server, and mobile environments, so it's safe to use them.
ES5 规范发布(2009 年 12 月)已近十年,几乎所有现代引擎都在桌面、服务器和移动环境中实现了它,因此使用它们是安全的。
And with the ES6 arrow function syntax, it's even more succinct:
使用 ES6 箭头函数语法,它更加简洁:
array.forEach(item => console.log(item));
Arrow functions are also widely implemented unless you plan to support ancient platforms (e.g., IE11); you are also safe to go.
除非您计划支持古老的平台(例如 IE11),否则箭头函数也被广泛实现;你也可以安全去。
Pros
优点
- Very short and succinct.
- Declarative
- 非常简短和简洁。
- 声明式
Cons
缺点
- Cannot use
break/continue
- 不能使用
break/continue
Normally, you can replace the need to breakout of imperative loops by filtering the array elements before iterating them, for example:
通常,您可以break通过在迭代之前过滤数组元素来代替退出命令式循环的需要,例如:
array.filter(item => item.condition < 10)
.forEach(item => console.log(item))
Keep in mind if you are iterating an array to build another array from it, you should use map, I've seen this anti-pattern so many times.
请记住,如果您要迭代一个数组以从中构建另一个数组,则应该使用map,我已经多次看到这种反模式。
Anti-pattern:
反模式:
const numbers = [1,2,3,4,5], doubled = [];
numbers.forEach((n, i) => { doubled[i] = n * 2 });
Proper use case of map:
map 的正确用例:
const numbers = [1,2,3,4,5];
const doubled = numbers.map(n => n * 2);
console.log(doubled);
Also, if you are trying to reducethe array to a value, for example, you want to sum an array of numbers, you should use the reducemethod.
此外,如果您试图将数组缩减为一个值,例如,您想要对一个数字数组求和,则应使用reduce方法。
Anti-pattern:
反模式:
const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });
Proper use of reduce:
正确使用reduce:
const numbers = [1,2,3,4,5];
const sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum);
3. ES6 for-ofstatement
3. ES6for-of语句
The ES6 standard introduces the concept of iterable objects and defines a new construct for traversing data, the for...ofstatement.
ES6 标准引入了可迭代对象的概念,并定义了一种用于遍历数据的新结构,即for...of语句。
This statement works for any kind of iterable object and also for generators (any object that has a [Symbol.iterator]property).
此语句适用于任何类型的可迭代对象以及生成器(任何具有[Symbol.iterator]属性的对象)。
Array objects are by definition built-in iterables in ES6, so you can use this statement on them:
根据定义,数组对象是 ES6 中的内置可迭代对象,因此您可以对它们使用以下语句:
let colors = ['red', 'green', 'blue'];
for (const color of colors){
console.log(color);
}
Pros
优点
- It can iterate over a large variety of objects.
- Can use normal flow control statements (
break/continue). - Useful to iterate serially asynchronous values.
- 它可以迭代各种各样的对象。
- 可以使用普通的流控制语句(
break/continue)。 - 用于迭代串行异步值。
Cons
缺点
- If you are targeting older browsers, the transpiled output might surprise you.
- 如果您针对的是较旧的浏览器,则转换后的输出可能会让您大吃一惊。
Do not use for...in
不使用 for...in
@zipcodeman suggests the use of the for...instatement, but for iterating arrays for-inshould be avoided, that statement is meant to enumerateobject properties.
@zipcodeman 建议使用该for...in语句,但for-in应避免迭代数组,该语句旨在枚举对象属性。
It shouldn't be used for array-like objects because:
它不应该用于类似数组的对象,因为:
- The order of iteration is not guaranteed; the array indexes may not be visited in numeric order.
- Inherited properties are also enumerated.
- 迭代顺序不保证;不能按数字顺序访问数组索引。
- 还枚举了继承的属性。
The second point is that it can give you a lot of problems, for example, if you extend the Array.prototypeobject to include a method there, that property will also be enumerated.
第二点是它会给你带来很多问题,例如,如果你扩展Array.prototype对象以在那里包含一个方法,那么该属性也会被枚举。
For example:
例如:
Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];
for (var i in array) {
console.log(array[i]);
}
The above code will console log "a", "b", "c", and "foo!".
上面的代码将控制台记录“a”、“b”、“c”和“foo!”。
That be particularly a problem if you use some library that relies heavily on native prototypes augmentation (such as MooTools, for example).
如果您使用一些严重依赖本机原型增强的库(例如 MooTools),这将是一个特别的问题。
The for-instatement as I said before is there to enumerateobject properties, for example:
for-in我之前说过的语句是为了枚举对象属性,例如:
var obj = {
"a": 1,
"b": 2,
"c": 3
};
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
// or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
console.log("prop: " + prop + " value: " + obj[prop])
}
}
In the above example, the hasOwnPropertymethod allows you to enumerate only own properties, that's it, only the properties that the object physically has, no inherited properties.
在上面的例子中,该hasOwnProperty方法允许你只枚举自己的属性,就是这样,只有对象物理上拥有的属性,没有继承的属性。
I would recommend you to read the following article:
我建议您阅读以下文章:
回答by Mark Reed
Yes, assuming your implementation includes the for...offeature introduced in ECMAScript 2015(the "Harmony" release)... which is a pretty safe assumption these days.
是的,假设您的实现包括for...of在ECMAScript 2015(“Harmony”版本)中引入的功能...现在这是一个非常安全的假设。
It works like this:
它是这样工作的:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
Or better yet, since ECMAScript 2015 also provides block-scoped variables:
或者更好,因为 ECMAScript 2015 还提供了块范围的变量:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
(The variable sis different on each iteration, but can still be declared constinside the loop body as long as it isn't modified there.)
(变量s在每次迭代中都不同,但仍然可以const在循环体内声明,只要它没有在那里修改。)
A note on sparse arrays: an array in JavaScript may not actually store as many items as reported by its length; that reported number is simply one greater than the highest index at which a value is stored. If the array holds fewer elements than indicated by its length, its said to be sparse. For example, it's perfectly legitimate to have an array with items only at indexes 3, 12, and 247; the lengthof such an array is reported as 248, though it is only actually storing 3 values. If you try to access an item at any other index, the array will appear to have the undefinedvalue there. So when you want to "loop through" an array, you have a question to answer: do you want to loop over the full range indicated by its length and process undefineds for any missing elements, or do you only want to process the elements actually present? There are plenty of applications for both approaches; it just depends on what you're using the array for.
关于稀疏数组的注意事项:JavaScript 中的数组实际上可能没有其报告的那样多的项目length;报告的数字仅比存储值的最高索引大 1。如果数组包含的元素少于其长度指示的元素,则称其为sparse。例如,拥有一个仅包含索引 3、12 和 247 项的数组是完全合法的;在length这样的阵列的报告为248,尽管它仅实际存储3个值。如果您尝试访问任何其他索引处的项目,该数组将显示为那里的undefined值。所以当你想“循环”一个数组时,你有一个问题要回答:你想循环遍历它的长度和过程指示的整个范围吗?undefineds 对于任何缺失的元素,还是只想处理实际存在的元素?这两种方法都有很多应用;它只取决于您使用数组的目的。
If you iterate over an array with for..of, the body of the loop is executed lengthtimes, and the loop control variable is set to undefinedfor any items not actually present in the array. Depending on the details of your "do something with" code, that behavior may be what you want, but if not, you should use a different approach.
如果您使用for..迭代数组,of循环体将执行length多次,并且循环控制变量被设置undefined为数组中实际不存在的任何项目。根据“使用”代码的详细信息,该行为可能是您想要的,但如果不是,您应该使用不同的方法。
Of course, some developers have no choice but to use a different approach anyway, because for whatever reason they're targeting a version of JavaScript that doesn't yet support for...of.
当然,一些开发人员别无选择,只能使用不同的方法,因为无论出于何种原因,他们的目标是尚不支持for...的 JavaScript 版本of。
As long as your JavaScript implementation is compliant with the previousedition of the ECMAScript specification (which rules out, for example, versions of Internet Explorer before 9), then you can use the Array#forEachiterator method instead of a loop. In that case, you pass a function to be called on each item in the array:
只要您的 JavaScript 实现符合ECMAScript 规范的先前版本(例如排除 Internet Explorer 9 之前的版本),您就可以使用Array#forEach迭代器方法而不是循环。在这种情况下,您传递一个要在数组中的每个项目上调用的函数:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
Unlike for...of, .forEachonly calls the function for elements that are actually present in the array. If passed our hypothetical array with three elements and a length of 248, it will only call the function three times, not 248 times. It also distinguishes between missing elements and elements that are actually set to undefined; for the latter, it will still call the function, passing undefinedas the argument. If this is how you want to handle sparse arrays, .forEachmay be the way to go even if your interpreter supports for...of.
与for...不同of,.forEach仅对数组中实际存在的元素调用该函数。如果通过我们的假设数组,包含三个元素,长度为 248,它只会调用函数 3 次,而不是 248 次。它还区分丢失的元素和实际设置为的元素undefined;对于后者,它仍然会调用函数,undefined作为参数传递。如果这是您想要处理稀疏数组.forEach的方式,即使您的解释器支持for...也可能是一种方法of。
The final option, which works in allversions of JavaScript, is an explicit counting loop. You simply count from 0 up to one less than the length and use the counter as an index. The basic loop looks like this:
最后一个选项适用于所有版本的 JavaScript,是显式计数循环。您只需从 0 数到比长度小 1 的次数,然后将计数器用作索引。基本循环如下所示:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
One advantage of this approach is that you can choose how to handle sparse arrays; the above code will run the body of the loop the full lengthtimes, with sset to undefinedfor any missing elements, just like for..of. If you instead want to handle only the actually-present elements of a sparse array, like .forEach, you can add a simple intest on the index:
这种方法的一个优点是您可以选择如何处理稀疏数组;上面的代码将运行循环的完整的身体length倍,s设置为undefined所有缺少的元素,就像for.. of。如果您只想处理稀疏数组的实际存在元素,例如.forEach,您可以in在索引上添加一个简单的测试:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
if (i in myStringArray) {
s = myStringArray[i];
// ... do something with s ...
}
}
Assigning the length value to the local variable (as opposed to including the full myStringArray.lengthexpression in the loop condition) can make a significant difference in performance since it skips a property lookup each time through; using Rhino on my machine, the speedup is 43%.
将长度值分配给局部变量(而不是myStringArray.length在循环条件中包含完整表达式)可以显着提高性能,因为它每次都跳过属性查找;在我的机器上使用 Rhino,加速是 43%。
You may see the length caching done in the loop initialization clause, like this:
您可能会在循环初始化子句中看到长度缓存,如下所示:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
The explicit counting loop also means you have access to the index of each value, should you want it. The index is also passed as an extra parameter to the function you pass to forEach, so you can access it that way as well:
如果需要,显式计数循环还意味着您可以访问每个值的索引。索引也作为额外参数传递给您传递给的函数forEach,因此您也可以通过这种方式访问它:
myStringArray.forEach( function(s, i) {
// ... do something with s and i ...
});
for...ofdoesn't give you the index associated with each object, but as long as the object you're iterating over is actually an Array(for..ofworks for other iterable types which may not have this method), you can use the Array#entriesmethod to change it to an array of [index, item] pairs, and then iterate over that:
for...of没有给你与每个对象关联的索引,但只要你迭代的对象实际上是一个Array( for..of适用于可能没有这个方法的其他可迭代类型),你就可以使用Array #entries方法将其更改为 [index, item] 对数组,然后对其进行迭代:
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
The for...insyntax mentioned by others is for looping over an object's properties; since an Array in JavaScript is just an object with numeric property names (and an automatically-updated lengthproperty), you can theoretically loop over an Array with it. But the problem is that it doesn't restrict itself to the numeric property values (remember that even methods are actually just properties whose value is a closure), nor is it guaranteed to iterate over those in numeric order. Therefore, the for...insyntax should notbe used for looping through Arrays.
其他人提到的for...in语法用于循环对象的属性;由于 JavaScript 中的 Array 只是一个具有数字属性名称(和一个自动更新的length属性)的对象,理论上您可以使用它循环遍历一个 Array。但问题是它并不将自己限制为数字属性值(请记住,即使方法实际上也只是其值为闭包的属性),也不能保证按数字顺序迭代这些值。因此,for...in语法不应用于循环遍历数组。
回答by hasen
You can use map, which is a functional programming technique that's also available in other languages like Pythonand Haskell.
您可以使用map,这是一种函数式编程技术,在Python和Haskell等其他语言中也可用。
[1,2,3,4].map( function(item) {
alert(item);
})
The general syntax is:
一般语法是:
array.map(func)
In general funcwould take one parameter, which is an item of the array. But in the case of JavaScript, it can take a second parameter which is the item's index, and a third parameter which is the array itself.
通常func会采用一个参数,它是数组的一项。但是在 JavaScript 的情况下,它可以采用第二个参数作为项目的索引,以及第三个参数作为数组本身。
The return value of array.mapis another array, so you can use it like this:
的返回值array.map是另一个数组,因此您可以像这样使用它:
var x = [1,2,3,4].map( function(item) {return item * 10;});
And now x is [10,20,30,40].
现在 x 是[10,20,30,40]。
You don't have to write the function inline. It could be a separate function.
您不必编写内联函数。它可以是一个单独的功能。
var item_processor = function(item) {
// Do something complicated to an item
}
new_list = my_list.map(item_processor);
which would be sort-of equivalent to:
这相当于:
for (item in my_list) {item_processor(item);}
Except you don't get the new_list.
除非你没有得到new_list.
回答by sebarmeli
In JavaScript it's not advisable to loop through an Array with a for-in loop, but it's better to use a forloop such as:
在 JavaScript 中,不建议使用 for-in 循环遍历数组,但最好使用如下for循环:
for(var i=0, len=myArray.length; i < len; i++){}
It's optimized as well ("caching" the array length). If you'd like to learn more, read my post on the subject.
它也进行了优化(“缓存”数组长度)。如果您想了解更多信息,请阅读我关于该主题的帖子。
回答by Marlon Bernardes
for (let s of myStringArray) {
for (let s of myStringArray) {
(Directly answering your question: now you can!)
(直接回答你的问题:现在你可以了!)
Most other answers are right, but they do not mention (as of this writing) that ECMA Script 6 2015is bringing a new mechanism for doing iteration, the for..ofloop.
大多数其他答案是正确的,但他们没有提到(在撰写本文时)ECMA Script 6 2015带来了一种新的迭代机制,即for..of循环。
This new syntax is the most elegant way to iterate an array in javascript (as long you don't need the iteration index).
这种新语法是在 javascript 中迭代数组的最优雅方式(只要您不需要迭代索引)。
It currently works with Firefox 13+, Chrome 37+ and it does not natively work with other browsers (see browser compatibility below). Luckily we have JS compilers (such as Babel) that allow us to use next-generation features today.
它目前适用于 Firefox 13+、Chrome 37+,并且它本身不适用于其他浏览器(请参阅下面的浏览器兼容性)。幸运的是,我们有 JS 编译器(例如Babel),可以让我们今天使用下一代功能。
It also works on Node (I tested it on version 0.12.0).
它也适用于 Node(我在 0.12.0 版上测试过)。
Iterating an array
迭代数组
// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
console.log(letter);
}
Iterating an array of objects
迭代对象数组
var band = [
{firstName : 'John', lastName: 'Lennon'},
{firstName : 'Paul', lastName: 'McCartney'}
];
for(var member of band){
console.log(member.firstName + ' ' + member.lastName);
}
Iterating a generator:
迭代生成器:
(example extracted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
(示例摘自https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
function* fibonacci() { // a generator function
let [prev, curr] = [1, 1];
while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}
for (let n of fibonacci()) {
console.log(n);
// truncate the sequence at 1000
if (n >= 1000) {
break;
}
}
Compatibility table:http://kangax.github.io/es5-compat-table/es6/#For..of loops
兼容性表:http : //kangax.github.io/es5-compat-table/es6/#For..of loops
Spec:http://wiki.ecmascript.org/doku.php?id=harmony:iterators
规范:http ://wiki.ecmascript.org/doku.php? id= harmony: iterators
}
}
回答by kennebec
Opera, Safari, Firefox and Chrome now all share a set of enhanced Array methods for optimizing many common loops.
Opera、Safari、Firefox 和 Chrome 现在都共享一组增强的 Array 方法来优化许多常见循环。
You may not need all of them, but they can be very useful, or would be if every browser supported them.
您可能不需要所有这些,但它们可能非常有用,或者如果每个浏览器都支持它们的话。
Mozilla Labs published the algorithms they and WebKitboth use, so that you can add them yourself.
Mozilla Labs 发布了它们和WebKit都使用的算法,因此您可以自己添加它们。
filterreturns an array of items that satisfy some condition or test.
filter返回满足某些条件或测试的项目数组。
everyreturns true if every array member passes the test.
如果每个数组成员都通过测试,则every返回 true。
somereturns true if any pass the test.
如果有任何通过测试,一些返回true。
forEachruns a function on each array member and doesn't return anything.
forEach对每个数组成员运行一个函数并且不返回任何内容。
mapis like forEach, but it returns an array of the results of the operation for each element.
map类似于 forEach,但它返回一个数组,其中包含每个元素的操作结果。
These methods all take a function for their first argument and have an optional second argument, which is an object whose scope you want to impose on the array members as they loop through the function.
这些方法都采用一个函数作为它们的第一个参数,并有一个可选的第二个参数,这是一个对象,当数组成员循环遍历函数时,您希望将其范围强加给数组成员。
Ignore it until you need it.
忽略它,直到你需要它。
indexOfand lastIndexOffind the appropriate position of the first or last element that matches its argument exactly.
indexOf和lastIndexOf找到与其参数完全匹配的第一个或最后一个元素的适当位置。
(function(){
var p, ap= Array.prototype, p2={
filter: function(fun, scope){
var L= this.length, A= [], i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
val= this[i];
if(fun.call(scope, val, i, this)){
A[A.length]= val;
}
}
++i;
}
}
return A;
},
every: function(fun, scope){
var L= this.length, i= 0;
if(typeof fun== 'function'){
while(i<L){
if(i in this && !fun.call(scope, this[i], i, this))
return false;
++i;
}
return true;
}
return null;
},
forEach: function(fun, scope){
var L= this.length, i= 0;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
fun.call(scope, this[i], i, this);
}
++i;
}
}
return this;
},
indexOf: function(what, i){
i= i || 0;
var L= this.length;
while(i< L){
if(this[i]=== what)
return i;
++i;
}
return -1;
},
lastIndexOf: function(what, i){
var L= this.length;
i= i || L-1;
if(isNaN(i) || i>= L)
i= L-1;
else
if(i< 0) i += L;
while(i> -1){
if(this[i]=== what)
return i;
--i;
}
return -1;
},
map: function(fun, scope){
var L= this.length, A= Array(this.length), i= 0, val;
if(typeof fun== 'function'){
while(i< L){
if(i in this){
A[i]= fun.call(scope, this[i], i, this);
}
++i;
}
return A;
}
},
some: function(fun, scope){
var i= 0, L= this.length;
if(typeof fun== 'function'){
while(i<L){
if(i in this && fun.call(scope, this[i], i, this))
return true;
++i;
}
return false;
}
}
}
for(p in p2){
if(!ap[p])
ap[p]= p2[p];
}
return true;
})();
回答by John Slegers
Intro
介绍
Since my time in college, I've programmed in Java, JavaScript, Pascal, ABAP, PHP, Progress 4GL, C/C++ and possibly a few other languages I can't think of right now.
从上大学开始,我就用 Java、JavaScript、Pascal、ABAP、PHP、Progress 4GL、C/C++ 以及可能我现在想不到的其他一些语言进行了编程。
While they all have their own linguistic idiosyncrasies, each of these languages share many of the same basic concepts. Such concepts include procedures / functions, IF-statements, FOR-loops, and WHILE-loops.
虽然它们都有自己的语言特性,但这些语言中的每一种都有许多相同的基本概念。这些概念包括过程/函数、-IF语句、-FOR循环和-WHILE循环。
A traditional for-loop
一个传统的for循环
A traditional forloop has three components:
传统的for循环包含三个组件:
- The initialization:executed before the look block is executed the first time
- The condition:checks a condition every time before the loop block is executed, and quits the loop if false
- The afterthought:performed every time after the loop block is executed
- 初始化:在look块第一次执行之前执行
- 条件:每次执行循环块前检查一个条件,如果为假则退出循环
- 事后思考:每次循环块执行后执行
These three components are separated from each other by a ;symbol. Content for each of these three components is optional, which means that the following is the most minimal forloop possible:
这三个组件由一个;符号相互隔开。这三个组件中的每一个的内容都是可选的,这意味着以下是for可能的最小循环:
for (;;) {
// Do stuff
}
Of course, you will need to include an if(condition === true) { break; }or an if(condition === true) { return; }somewhere inside that for-loop to get it to stop running.
当然,您需要在该-loop 中if(condition === true) { break; }的if(condition === true) { return; }某处包含一个或一个,for以使其停止运行。
Usually, though, the initialization is used to declare an index, the condition is used to compare that index with a minimum or maximum value, and the afterthought is used to increment the index:
但是,通常初始化用于声明索引,条件用于将该索引与最小值或最大值进行比较,事后用于增加索引:
for (var i = 0, length = 10; i < length; i++) {
console.log(i);
}
Using a traditional forloop to loop through an array
使用传统for循环遍历数组
The traditional way to loop through an array, is this:
循环遍历数组的传统方法是:
for (var i = 0, length = myArray.length; i < length; i++) {
console.log(myArray[i]);
}
Or, if you prefer to loop backwards, you do this:
或者,如果您更喜欢向后循环,您可以这样做:
for (var i = myArray.length - 1; i > -1; i--) {
console.log(myArray[i]);
}
There are, however, many variations possible, like for example this one:
然而,有许多变化是可能的,例如这个:
for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
console.log(value);
}
...or this one...
……或者这个……
var i = 0, length = myArray.length;
for (; i < length;) {
console.log(myArray[i]);
i++;
}
...or this one:
...或者这个:
var key = 0, value;
for (; value = myArray[key++];){
console.log(value);
}
Whichever works best is largely a matter of both personal taste and the specific use case you're implementing.
无论哪种效果最好,很大程度上取决于个人品味和您正在实施的特定用例。
Note that each of these variations is supported by all browsers, including very very old ones!
请注意,所有浏览器都支持这些变体中的每一个,包括非常非常老的浏览器!
A whileloop
一个while循环
One alternative to a forloop is a whileloop. To loop through an array, you could do this:
for循环的一种替代方法是while循环。要遍历数组,您可以这样做:
var key = 0;
while(value = myArray[key++]){
console.log(value);
}
Like traditional forloops, whileloops are supported by even the oldest of browsers.
与传统for循环一样,while即使是最古老的浏览器也支持循环。
Also, note that every while loop can be rewritten as a forloop. For example, the whileloop hereabove behaves the exact same way as this for-loop:
另外,请注意,每个 while 循环都可以重写为一个for循环。例如,上述while循环的行为方式与此for-loop完全相同:
for(var key = 0; value = myArray[key++];){
console.log(value);
}
For...inand for...of
For...in和 for...of
In JavaScript, you can also do this:
在 JavaScript 中,您也可以这样做:
for (i in myArray) {
console.log(myArray[i]);
}
This should be used with care, however, as it doesn't behave the same as a traditional forloop in all cases, and there are potential side-effects that need to be considered. See Why is using "for...in" with array iteration a bad idea?for more details.
但是,这应该谨慎使用,因为它for在所有情况下都与传统循环的行为不同,并且需要考虑潜在的副作用。请参阅为什么在数组迭代中使用“for...in”是个坏主意?更多细节。
As an alternative to for...in, there's now also for for...of. The following example shows the difference between a for...ofloop and a for...inloop:
作为 的替代for...in,现在还有 for for...of。以下示例显示了for...of循环和for...in循环之间的区别:
var myArray = [3, 5, 7];
myArray.foo = "hello";
for (var i in myArray) {
console.log(i); // logs 0, 1, 2, "foo"
}
for (var i of myArray) {
console.log(i); // logs 3, 5, 7
}
Additionally, you need to consider that no version of Internet Explorer supports for...of(Edge 12+does) and that for...inrequires at least Internet Explorer 10.
此外,您需要考虑没有任何版本的 Internet Explorer 支持for...of(Edge 12+支持)并且for...in至少需要 Internet Explorer 10。
Array.prototype.forEach()
Array.prototype.forEach()
An alternative to for-loops is Array.prototype.forEach(), which uses the following syntax:
for-loops的替代方法是Array.prototype.forEach(),它使用以下语法:
myArray.forEach(function(value, key, myArray) {
console.log(value);
});
Array.prototype.forEach()is supported by all modern browsers, as well as Internet Explorer 9 and later.
Array.prototype.forEach()所有现代浏览器以及 Internet Explorer 9 及更高版本都支持。
Libraries
图书馆
Finally, many utility libraries also have their own foreachvariation. AFAIK, the three most popular ones are these:
最后,许多实用程序库也有自己的foreach变体。AFAIK,最受欢迎的三个是:
jQuery.each(), in jQuery:
$.each(myArray, function(key, value) {
console.log(value);
});
_.each(), in Underscore.js:
_.each(myArray, function(value, key, myArray) {
console.log(value);
});
_.forEach(), in Lodash.js:
_.forEach(myArray, function(value, key) {
console.log(value);
});
回答by Timo Huovinen
Use the while loop...
使用while循环...
var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
console.log(item);
}
logs: 'one','two','three'
日志:“一”、“二”、“三”
And for the reverse order, an even more efficient loop
对于相反的顺序,一个更有效的循环
var items = ['one','two','three'], i = items.length;
while(i--){
console.log(items[i]);
}
logs: 'three','two','one'
日志:“三”、“二”、“一”
Or the classical forloop
或者经典for循环
var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
console.log(items[i]);
}
logs: 'one','two','three'
日志:“一”、“二”、“三”
Reference: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/
参考:http: //www.sitepoint.com/google-closure-how-not-to-write-javascript/
回答by Phrogz
If you want a terse way to write a fast loop andyou can iterate in reverse:
如果您想要一种简洁的方式来编写快速循环,并且可以反向迭代:
for (var i=myArray.length;i--;){
var item=myArray[i];
}
This has the benefit of caching the length (similar to for (var i=0, len=myArray.length; i<len; ++i)and unlike for (var i=0; i<myArray.length; ++i)) while being fewer characters to type.
这样做的好处是可以缓存长度(类似于for (var i=0, len=myArray.length; i<len; ++i)和不同for (var i=0; i<myArray.length; ++i)),同时输入的字符更少。
There are even some times when you ought to iterate in reverse, such as when iterating over a live NodeListwhere you plan on removing items from the DOM during iteration.
甚至有时您应该反向迭代,例如在迭代活动 NodeList 时,您计划在迭代期间从 DOM 中删除项目。
回答by Yuci
Some use cases of looping through an array in the functional programming wayin JavaScript:
在 JavaScript中以函数式编程方式循环遍历数组的一些用例:
1. Just loop through an array
1. 循环遍历一个数组
const myArray = [{x:100}, {x:200}, {x:300}];
myArray.forEach((element, index, array) => {
console.log(element.x); // 100, 200, 300
console.log(index); // 0, 1, 2
console.log(array); // same myArray object 3 times
});
Note: Array.prototype.forEach() is not a functional way strictly speaking, as the function it takes as the input parameter is not supposed to return a value, which thus cannot be regarded as a pure function.
注意:Array.prototype.forEach() 严格来说不是函数式的,因为它作为输入参数的函数不应该返回值,因此不能被视为纯函数。
2. Check if any of the elements in an array pass a test
2. 检查数组中的任何元素是否通过测试
const people = [
{name: 'John', age: 23},
{name: 'Andrew', age: 3},
{name: 'Peter', age: 8},
{name: 'Hanna', age: 14},
{name: 'Adam', age: 37}];
const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true
3. Transform to a new array
3.转换为新数组
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]
Note: The map() method creates a new array with the results of calling a provided function on every element in the calling array.
注意:map() 方法使用对调用数组中的每个元素调用提供的函数的结果创建一个新数组。
4. Sum up a particular property, and calculate its average
4.总结一个特定的属性,并计算它的平均值
const myArray = [{x:100}, {x:200}, {x:300}];
const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300
const average = sum / myArray.length;
console.log(average); // 200
5. Create a new array based on the original but without modifying it
5.在原数组的基础上新建一个不修改的数组
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => {
return {
...element,
x: element.x * 2
};
});
console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]
6. Count the number of each category
6.统计每个类别的数量
const people = [
{name: 'John', group: 'A'},
{name: 'Andrew', group: 'C'},
{name: 'Peter', group: 'A'},
{name: 'James', group: 'B'},
{name: 'Hanna', group: 'A'},
{name: 'Adam', group: 'B'}];
const groupInfo = people.reduce((groups, person) => {
const {A = 0, B = 0, C = 0} = groups;
if (person.group === 'A') {
return {...groups, A: A + 1};
} else if (person.group === 'B') {
return {...groups, B: B + 1};
} else {
return {...groups, C: C + 1};
}
}, {});
console.log(groupInfo); // {A: 3, C: 1, B: 2}
7. Retrieve a subset of an array based on particular criteria
7. 根据特定条件检索数组的子集
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}]
Note: The filter() method creates a new array with all elements that pass the test implemented by the provided function.
注意: filter() 方法创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。
8. Sort an array
8.对数组进行排序
const people = [
{ name: "John", age: 21 },
{ name: "Peter", age: 31 },
{ name: "Andrew", age: 29 },
{ name: "Thomas", age: 25 }
];
let sortByAge = people.sort(function (p1, p2) {
return p1.age - p2.age;
});
console.log(sortByAge);
9. Find an element in an array
9. 在数组中查找元素
const people = [ {name: "john", age:23},
{name: "john", age:43},
{name: "jim", age:101},
{name: "bob", age:67} ];
const john = people.find(person => person.name === 'john');
console.log(john);
The Array.prototype.find() method returns the value of the first element in the array that satisfies the provided testing function.
Array.prototype.find() 方法返回数组中满足提供的测试函数的第一个元素的值。


