如何使用JavaScript循环遍历数组中的所有条目?
我认为是这样的:
forEach(instance in theArray)
theArray
是我的数组,但这似乎不正确。
答案 0 :(得分:481)
修改:这个答案毫无希望地过时了。有关更现代的方法,请查看the methods available on an array。感兴趣的方法可能是:
在JavaScript中迭代数组的标准方法是一个vanilla for
循环:
var length = arr.length,
element = null;
for (var i = 0; i < length; i++) {
element = arr[i];
// Do something with element
}
但请注意,只有拥有密集数组且每个索引都被一个元素占用时,此方法才有用。如果数组是稀疏的,那么你可能会遇到这种方法的性能问题,因为你将迭代很多真正存在于数组中的索引。在这种情况下,for .. in
循环可能是一个更好的主意。 但是,您必须使用适当的安全措施来确保只对数组的所需属性(即数组元素)起作用,因为for..in
- 循环也将被枚举在旧版浏览器中,或者如果其他属性定义为enumerable
。
在ECMAScript 5中,阵列原型上会有一个forEach方法,但旧版浏览器不支持它。因此,为了能够始终如一地使用它,您必须具有支持它的环境(例如,服务器端JavaScript的Node.js),或使用“Polyfill”。然而,Polyfill对于这个功能来说是微不足道的,因为它使代码更容易阅读,所以它是一个很好的polyfill。
答案 1 :(得分:219)
如果您使用的是jQuery库,则可以使用jQuery.each:
$.each(yourArray, function(index, value) {
// do your stuff here
});
编辑:
根据问题,用户需要javascript中的代码而不是jquery,因此编辑是
var length = yourArray.length;
for (var i = 0; i < length; i++) {
// Do something with yourArray[i].
}
答案 2 :(得分:97)
我认为 reverse for循环值得一提:
for (var i = array.length; i--; ) {
// process array[i]
}
len
变量,也不需要在每次迭代时与array.length
进行比较,其中任何一项都可能是一次性优化。array[i]
删除或插入项目),然后转发循环将跳过向左移动到位置 i 的项目,或者重新处理向右移动的 i 项目。在传统的for循环中,可以更新 i 以指向需要处理的下一个项目 - 1,但简单地反转迭代方向通常是更简单和more elegant solution。forEach()
和ES6&#39; for ... of
。一些开发人员默认使用reverse for循环 ,除非有充分的理由进行循环。
虽然性能提升通常微不足道,但它有点尖叫:
&#34;只需对列表中的每个项目执行此操作,我都不关心订单!&#34;
然而,在实践中不实际上是意图的可靠指示,因为它与 关心的情况无法区分订单,并且确实 需要 以反向循环。因此,实际上需要另一种结构来准确表达“不关心”#34; intent,大多数语言中目前不可用的东西,包括ECMAScript,但可以调用,例如,forEachUnordered()
。
如果订单无关紧要,并且效率是一个问题(在游戏或动画引擎的最内层循环中),则可以接受使用反向循环作为您的进入模式。请记住,在现有代码中看到反向循环并不一定意味着订单无关紧要!
一般情况下,对于更高级别的代码,清晰度和安全性是更受关注的问题,我建议您使用Array::forEach
作为默认模式:
for
和while
循环中总是可能出现意外隐藏。)然后,当您在代码中看到反向循环时,这是一个暗示它被推翻的原因很充分(可能是上述原因之一)。并且看到传统的前向循环可能表明可能发生转移。
(如果对意图的讨论对你没有意义,那么你和你的代码可能会受益于观看Crockford关于Programming Style & Your Brain的讲座。)
for (var i = 0; i < array.length; i++) { ... } // Forwards
for (var i = array.length; i--; ) { ... } // Reverse
您会注意到i--
是中间子句(我们通常会看到比较),最后一个子句是空的(我们通常会看到i++
)。这意味着i--
也可用作条件来继续。至关重要的是,它会在每次迭代之前执行并检查。
如何在没有爆炸的情况下从array.length
开始?
因为i--
在每次迭代之前运行,所以在第一次迭代中我们实际上将访问array.length - 1
处的项目,这避免了 Array-out-的任何问题of-bounds undefined
项。
为什么它不会在索引0之前停止迭代?
当条件i--
求值为假值(当它产生0时)时,循环将停止迭代。
诀窍在于,与--i
不同,尾随i--
运算符会递减i
,但会在 递减之前产生值 。您的控制台可以证明这一点:
> var i = 5; [i, i--, i];
[5, 5, 4]
所以在最后一次迭代中, i 以前是 1 而i--
表达式将其更改为 0 但实际上产生<强> 1 (真实),所以条件通过。在下一次迭代i--
将 i 更改为 -1 但产生 0 (falsey),导致执行立即退出循环的底部。
在循环的传统前锋中,i++
和++i
是可以互换的(正如Douglas Crockford指出的那样)。但是在反向for循环中,因为我们的减量也是我们的条件表达式,如果我们想在索引0处理项目,我们必须坚持使用i--
。
有些人喜欢在反向for
循环中画一个小箭头,并以眨眼结束:
for (var i = array.length; i --> 0 ;) {
积分转到WYL,向我展示反向循环的好处和恐怖。
答案 3 :(得分:76)
某些C样式语言使用foreach
循环枚举。在JavaScript中,这是使用for..in
loop structure:
var index,
value;
for (index in obj) {
value = obj[index];
}
有一个问题。 for..in
将循环遍历每个对象的可枚举成员以及其原型上的成员。要避免读取通过对象原型继承的值,只需检查属性是否属于对象:
for (i in obj) {
if (obj.hasOwnProperty(i)) {
//do stuff
}
}
此外,ECMAScript 5已向Array.prototype
添加forEach
方法,该方法可用于使用calback枚举数组(polyfill位于文档中,因此您仍然可以使用它对于旧浏览器):
arr.forEach(function (val, index, theArray) {
//do stuff
});
重要的是要注意,当回调返回Array.prototype.forEach
时,false
不会中断。 jQuery和Underscore.js在each
上提供了自己的变体,以提供可以短路的循环。
答案 4 :(得分:36)
如果要循环数组,请使用标准的由三部分组成的for
循环。
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
您可以通过缓存myArray.length
或向后迭代来获得性能优化。
答案 5 :(得分:29)
我知道这是一篇很老的帖子,而且已经有很多很棒的答案了。为了更完整一点,我想我会使用AngularJS投入另一个。当然,这只适用于你使用Angular的情况,显然,无论如何我还是想把它放进去。
angular.forEach
需要2个参数和一个可选的第三个参数。第一个参数是迭代的对象(数组),第二个参数是迭代器函数,可选的第三个参数是对象上下文(在循环内部基本上称为'this'。
使用forEach循环的角度有不同的方法。最简单且可能最常用的是
var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
//item will be each element in the array
//do something
});
另一种将项目从一个数组复制到另一个数组的方法是
var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);
虽然,您不必这样做,但您可以简单地执行以下操作,它与上一个示例相同:
angular.forEach(temp, function(item) {
temp2.push(item);
});
现在有使用angular.forEach
函数的优点和缺点,而不是内置的vanilla-flavored for
循环。
<强>赞成强>
angular.forEach
将使用ES5 forEach循环。现在,我将在cons部分中获得效率,因为forEach循环比for循环多慢。我作为专业人士提到这一点,因为保持一致和标准化是件好事。考虑以下2个嵌套循环,这些循环完全相同。假设我们有2个对象数组,每个对象包含一个结果数组,每个结果都有一个Value属性,它是一个字符串(或其他)。并且假设我们需要迭代每个结果,如果它们相等则执行一些操作:
angular.forEach(obj1.results, function(result1) {
angular.forEach(obj2.results, function(result2) {
if (result1.Value === result2.Value) {
//do something
}
});
});
//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
for (var j = 0; j < obj2.results.length; j++) {
if (obj1.results[i].Value === obj2.results[j].Value) {
//do something
}
}
}
虽然这是一个非常简单的假设示例,但是我使用第二种方法编写了三次嵌入for循环,并且非常难以阅读,并为此写了。
<强>缺点强>
angular.forEach
和本地forEach
就此而言,比正常的for
循环慢得多......关于90% slower 。因此,对于大型数据集,最好坚持原生for
循环。continue
,要继续angular.forEach
,您可以在return;
函数中简单地添加angular.forEach(array, function(item) { if (someConditionIsTrue) return; });
语句,这将使其成为forEach
继续执行该迭代的功能。这也是由于本机for
不支持中断或继续。我确信还有其他各种优点和缺点,请随意添加您认为合适的任何内容。我觉得,如果你需要效率的话,最重要的是,坚持使用本地angular.forEach
循环来满足你的循环需求。但是,如果你的数据集较小并且可以放弃一些效率以换取可读性和可写性,那么无论如何都要在这个坏孩子中抛出{{1}}。
答案 6 :(得分:28)
forEach 实施(see in jsFiddle):
function forEach(list,callback) {
var length = list.length;
for (var n = 0; n < length; n++) {
callback.call(list[n]);
}
}
var myArray = ['hello','world'];
forEach(
myArray,
function(){
alert(this); // do something
}
);
答案 7 :(得分:25)
现在一个简单的解决方案是使用underscore.js library。它提供了许多有用的工具,例如each
,如果可用,它会自动将作业委派给本地forEach
。
A CodePen example它的工作原理是:
var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});
Array.prototype.forEach()
。for each (variable in object)
已被弃用为ECMA-357(EAX)标准的一部分。for (variable of object)
作为Harmony(ECMAScript 6)提案的一部分进行迭代的下一种方式。答案 8 :(得分:25)
jQuery中foreach
有三种实现方式如下。
var a = [3,2];
$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
答案 9 :(得分:23)
自ES6开始:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
of
避免与in
相关联的奇怪现象,并使其像任何其他语言的for
循环一样工作,let
绑定i
循环而不是函数。
当只有一个命令时(例如在上面的示例中),可以省略大括号({}
)。
答案 10 :(得分:23)
for(i = 0; i < array.length; i++)
循环可能不是最好的选择。为什么?如果你有这个:
var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";
该方法将从array[0]
致电array[2]
。首先,这将首先引用你甚至没有的变量,第二个你不会在数组中有变量,第三个会使代码更大胆。看这里,这就是我使用的:
for(var i in array){
var el = array[i];
//If you want 'i' to be INT just put parseInt(i)
//Do something with el
}
如果你想让它成为一个功能,你可以这样做:
function foreach(array, call){
for(var i in array){
call(array[i]);
}
}
如果你想打破一点逻辑:
function foreach(array, call){
for(var i in array){
if(call(array[i]) == false){
break;
}
}
}
示例:
foreach(array, function(el){
if(el != "!"){
console.log(el);
} else {
console.log(el+"!!");
}
});
它返回:
//Hello
//World
//!!!
答案 11 :(得分:17)
这是非稀疏列表的迭代器,其中索引从0开始,这是处理document.getElementsByTagName或document.querySelectorAll时的典型场景。
function each( fn, data ) {
if(typeof fn == 'string')
eval('fn = function(data, i){' + fn + '}');
for(var i=0, L=this.length; i < L; i++)
fn.call( this[i], data, i );
return this;
}
Array.prototype.each = each;
用法示例:
示例#1
var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]
示例#2
each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');
每个p标记获得class="blue"
示例#3
each.call(document.getElementsByTagName('p'),
"if( i % 2 == 0) this.className = data;",
'red'
);
其他每个p标记都会获得class="red"
&gt;
示例#4
each.call(document.querySelectorAll('p.blue'),
function(newClass, i) {
if( i < 20 )
this.className = newClass;
}, 'green'
);
最后,前20个蓝色p标签变为绿色
使用字符串作为函数时的注意事项:该函数是在上下文中创建的,只有在您确定变量作用域时才应该使用。否则,最好传递范围更直观的函数。
答案 12 :(得分:17)
原生JavaScript中没有for each
个循环。您可以使用库来获得此功能(我建议Underscore.js),在循环中使用简单的for
。
for (var instance in objects) {
...
}
但请注意,可能有理由使用更简单的for
循环(请参阅堆栈溢出问题 Why is using “for…in” with array iteration such a bad idea? )
var instance;
for (var i=0; i < objects.length; i++) {
var instance = objects[i];
...
}
答案 13 :(得分:16)
在JavaScript中循环数组有一些方法,如下所示:
- 这是最常见的一个。用于循环的完整代码块
var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
while - 在条件通过时循环播放。它似乎是最快的循环
var text = "";
var i = 0;
while (i < 10) {
text += i + ") something<br>";
i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
执行/同时 - 在条件为真时循环执行代码块,至少运行一次
var text = ""
var i = 0;
do {
text += i + ") something <br>";
i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>
功能循环 - forEach
,map
,filter
,还有reduce
(它们遍历函数,但如果您需要,则使用用你的阵列等做点什么。
// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>
有关数组上函数式编程的更多信息和示例,请查看博客文章 Functional programming in JavaScript: map, filter and reduce 。
答案 14 :(得分:14)
forEach
没有内置的能力。要中断执行,请使用下面的Array#some
:
[1,2,3].some(function(number) {
return number === 1;
});
这是有效的,因为只要以数组顺序执行的任何回调返回true,some
都会返回true,从而使其余的执行短路。
Original Answer
请参阅some
答案 15 :(得分:14)
ECMAScript5(Javascript上的版本)与Arrays一起使用。
forEach - 遍历数组中的每个项目,并为每个项目执行任何操作。
['C', 'D', 'E'].forEach(function(element, index) {
console.log(element + " is the #" + (index+1) + " in musical scale");
});
// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale
如果使用某些内置功能对阵列操作更感兴趣。
map - 它使用回调函数的结果创建一个新数组。当您需要格式化数组元素时,可以使用此方法。
// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
return elem.toUpperCase();
});
// Output: ['BOB', 'JOE', 'JEN']
reduce - 正如名称所说,它通过调用传入currenct元素的给定函数和先前执行的结果将数组减少为单个值。
[1,2,3,4].reduce(function(previous, current) {
return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10
每个 - 如果数组中的所有元素都在回调函数中传递测试,则返回true或false。
// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
return elem >= 18;
});
// Output: false
过滤器 - 非常类似于除过滤器之外的每个过滤器返回一个数组,其中的元素返回true给定的函数。
// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
return (elem % 2 == 0)
});
// Output: [2,4,6]
希望这会有用。
答案 16 :(得分:11)
我也希望将此作为反向循环的组合添加到上面,并为那些想要这种语法的人添加答案。
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
console.log(item);
}
<强>优点:强>
这样做的好处:你已经在第一个中有了引用,就像以后不需要用另一行声明一样。循环通过对象数组时很方便。
<强>缺点:强>
只要引用为false,这将会中断 - falsey(未定义等)。它可以作为一个优势使用。但是,它会让它更难阅读。此外,根据浏览器的不同,它可以“优化”,以便比原始浏览器更快地工作。
答案 17 :(得分:10)
使用$.map
的jQuery方式:
var data = [1, 2, 3, 4, 5, 6, 7];
var newData = $.map(data, function(element) {
if (element % 2 == 0) {
return element;
}
});
// newData = [2, 4, 6];
答案 18 :(得分:7)
在ES6 destructuring和spread operator中使用循环
事实证明,解构和使用散布运算符对于ES6的新手来说非常有用,因为它更易于阅读/美观,尽管有些javascript老手可能认为它比较杂乱,初级或其他人可能会觉得有用。
示例6、7和8 可以与
.map
,.filter
,.reduce
,.sort
,{{ 1}},.every
,有关这些方法的更多信息,请查看Array Object。
示例1:正常的.some
循环-这里没有技巧。
for...of
示例2:将单词拆分为字符
let arrSimple = ['a', 'b', 'c'];
for (let letter of arrSimple) {
console.log(letter);
}
示例3:使用let arrFruits = ['apple', 'orange', 'banana'];
for (let [firstLetter, ...restOfTheWord] of arrFruits) {
// Create a shallow copy using the spread operator
let [lastLetter] = [...restOfTheWord].reverse();
console.log(firstLetter, lastLetter, restOfTheWord);
}
和key
循环
value
示例4:内联获取对象属性
// let arrSimple = ['a', 'b', 'c'];
// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type:
// `arrWithIndex: [number, string][]`
let arrWithIndex = [
[0, 'a'],
[1, 'b'],
[2, 'c'],
];
// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);
// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);
for (let [key, value] of arrWithIndex) {
console.log(key, value);
}
示例5:获得所需的深层对象属性
let arrWithObjects = [{
name: 'Jon',
age: 32
},
{
name: 'Elise',
age: 33
}
];
for (let { name, age: aliasForAge } of arrWithObjects) {
console.log(name, aliasForAge);
}
示例6:是示例3 与let arrWithObjectsWithArr = [{
name: 'Jon',
age: 32,
tags: ['driver', 'chef', 'jogger']
},
{
name: 'Elise',
age: 33,
tags: ['best chef', 'singer', 'dancer']
}
];
for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
console.log(name, firstItemFromTags, restOfTags);
}
.forEach
示例7:是否与let arrWithIndex = [
[0, 'a'],
[1, 'b'],
[2, 'c'],
];
// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it
arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
console.log(forEachIndex, mappedIndex, item);
});
.forEach
示例8:是示例5 与let arrWithObjects = [{
name: 'Jon',
age: 32
},
{
name: 'Elise',
age: 33
}
];
// NOTE: Destructuring objects while using shorthand functions
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
console.log(name, aliasForAge)
});
.forEach
答案 19 :(得分:6)
最接近你想法的方法是使用Array.forEach()
接受将为数组的每个元素执行的clojure函数。
myArray.forEach(
(item) => {
// do something
console.log(item);
}
);
另一种可行的方法是使用Array.map()
,它以相同的方式工作,但每个元素也mutates
,并返回它:
var myArray = [1, 2, 3];
myArray = myArray.map(
(item) => {
return item + 1;
}
);
console.log(myArray); // [2, 3, 4]
答案 20 :(得分:5)
根据新的更新功能ECMAScript 6(ES6)和ECMAScript 2015,您可以在循环中使用以下选项:
用于循环
for(var i = 0; i < 5; i++){
console.log(i);
}
// Output: 0,1,2,3,4
用于...循环
let obj = {"a":1, "b":2}
for(let k in obj){
console.log(k)
}
// Output: a,b
Array.forEach()
let array = [1,2,3,4]
array.forEach((x) => {
console.log(x);
})
// Output: 1,2,3,4
用于...的循环
let array = [1,2,3,4]
for(let x of array){
console.log(x);
}
// Output: 1,2,3,4
while循环
let x = 0
while(x < 5){
console.log(x)
x++
}
// Output: 1,2,3,4
做...而循环
let x = 0
do{
console.log(x)
x++
}while(x < 5)
// Output: 1,2,3,4
答案 21 :(得分:5)
lambda语法通常不适用于IE 10或更低版本。
我通常使用
converters
答案 22 :(得分:4)
您可以像这样致电forEach
:let Array = [1,3,2];
theArray.forEach((element)=>{
// use the element of the array
console.log(element)
}
element具有从0到数组长度的每个索引的值。
输出:
1
3
2
说明:
forEach在原型类中。您也可以将其称为theArray.prototype.forEach(...);
原型: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b
您还可以像这样更改数组:
for(let i=0;i<theArray.length;i++){
console.log(i); //i will have the value of each index
}
答案 23 :(得分:4)
您可以使用: 1. ForEach
theArray.forEach(function (array, index) {
console.log(index);
console.log(array);
});
2.for
for(var i=0;i<theArray.length;i++){
console.log(i)
}
3.map
theArray.map(x => console.log(x));
4.map
theArray.filter(x => console.log(x));
还有很多其他需要迭代的地方
答案 24 :(得分:3)
假设我们有一系列主题:
let ddl = new Array();
if (subjects) {
subjects.forEach(function (s) {ddl.push({"id": s.id,"label": s.name});});
}
答案 25 :(得分:3)
如果要使用箭头功能遍历对象数组:
let arr=[{name:'john',age:50},{name:'clark',age:19},{name:'mohan',age:26}];
arr.forEach((person)=>{
console.log('i am '+person.name+' and i am '+person.age+ ' old');
})
答案 26 :(得分:2)
遍历数组时,我们通常可能希望实现以下目标之一:
我们要遍历数组并创建新数组:
Array.prototype.map
我们要遍历数组,而不要创建新的数组:
Array.prototype.forEach
for..of
循环
在JS中,有许多方法可以实现这两个目标。但是,有些比其他更方便。在下面,您可以找到一些常用的方法(最方便的imo)来完成javascript中的数组迭代。
Map
map()
是位于Array.prototype
上的函数,可以转换数组的每个元素,然后返回一个 new 数组。 map()
以回调函数作为参数,并以下列方式工作:
let arr = [1, 2, 3, 4, 5];
let newArr = arr.map((element, index, array) => {
return element * 2;
})
console.log(arr);
console.log(newArr);
我们已传递给map()
作为参数的回调函数,将对每个元素执行。然后返回一个数组,该数组的长度与原始数组的长度相同。在这个新数组元素中,回调函数将其作为参数传递给map()
。
map
与其他循环机制(如forEach
和for..of
循环)之间的明显区别在于, map
返回为新数组,而旧数组完好无损(除非您明确使用splice
之类的方式进行操作)。
还要注意,map
函数的回调提供了当前迭代的索引号作为第二个参数。此外,第三个参数是否提供了在其上调用map
的数组。有时,这些属性可能非常有用。
forEach
forEach
是位于Array.prototype
上的函数,该函数以回调函数作为参数。然后,它将对数组中的每个元素执行此回调函数。与map()
函数相反,forEach函数不返回任何内容(undefined
)。例如:
let arr = [1, 2, 3, 4, 5];
arr.forEach((element, index, array) => {
console.log(element * 2);
if (index === 4) {
console.log(array)
}
// index, and oldArray are provided as 2nd and 3th argument by the callback
})
console.log(arr);
就像map
函数一样,forEach
回调提供第二个参数作为当前迭代的索引号。第三个参数也提供在其上调用forEach
的数组。
for..of
for..of
循环遍历数组的每个元素(或任何其他可迭代对象)。它以以下方式工作:
let arr = [1, 2, 3, 4, 5];
for(let element of arr) {
console.log(element * 2);
}
在上面的示例中,element
代表数组元素,arr
是我们要循环的数组。并不是说element
是一个任意名称,我们可以选择其他任何名称,例如'el'或适用时更具声明性的名称。
不要将for..in
循环与for..of
循环混淆。 for..in
将循环遍历数组的所有可枚举属性,而for..of
循环将仅遍历数组元素。例如:
let arr = [1, 2, 3, 4, 5];
arr.foo = 'foo';
for(let element of arr) {
console.log(element);
}
for(let element in arr) {
console.log(element);
}
答案 27 :(得分:1)
如果您想使代码保持功能性,请使用map:
theArray.map(instance => do_something);
通过这种方式,您将为以后的操作生成新的数组,并将跳过任何不希望的副作用。
答案 28 :(得分:1)
今天18/12/2019,我在MacOs HighSierra 10.13.6,Chrome v 79.0,Safari v13.0.4和Firefox v71.0(64位)上进行了测试-有关优化的结论(通常micro-optimisation不值得将其引入代码中,因为收益很小,但是代码复杂度却不断提高。
看起来像传统的for
( Aa )是在所有浏览器上编写快速代码的不错选择。
C组中的其他解决方案,例如for-of
( Ad )。 ...通常是2x-10x(甚至更多)速度比 Aa 慢1倍,但是对于较小的数组,可以使用它-为了提高代码的清晰度。
n
( Ab,Bb,Be )中缓存有数组长度的循环有时更快,有时却没有。可能是编译器自动检测这种情况并引入缓存。缓存版本和非缓存版本( Aa,Ba,Bd )之间的速度差异约为1%-因此,简介n
是micro-optimisation。
类似i--
的解决方案,其中循环从最后一个数组元素( Ac,Bc )开始,通常比向前解决方案慢30%-可能是这样的的CPU memory cache working中的值-前向内存读取对于CPU缓存而言更为理想。 建议不要使用此类解决方案。
在测试中,我们计算数组元素的总和。我对小型数组(10个元素)和大型数组(1M元素)进行测试,并将它们分为3组:
for
个测试while
测试
let arr=[1,2,3,4,5,6,7,8,9,10];
//let arr = Array.from(Array(1000000), (x,i)=> i%10);
function Aa(a,s=0) {
for(let i=0; i<a.length; i++) { s+= a[i]; }
console.log('Aa=',s);
}
function Ab(a,s=0) {
let n= a.length;
for(let i=0; i<n; i++) { s+= a[i]; }
console.log('Ab=',s);
}
function Ac(a,s=0) {
for(let i=a.length; i--;) { s+= a[i]; }
console.log('Ac=',s);
}
function Ad(a,s=0) {
for(let x of a) { s+=x; }
console.log('Ad=',s);
}
function Ae(a,s=0) {
for(let i in a) if (a.hasOwnProperty(i)) { s+=a[i]; }
console.log('Ae=',s);
}
function Ba(a,s=0) {
let i= -1;
while(++i < a.length) { s+= a[i]; }
console.log('Ba=',s);
}
function Bb(a,s=0) {
let i= -1; let n= a.length;
while(++i < n) { s+= a[i]; }
console.log('Bb=',s);
}
function Bc(a,s=0) {
let i=a.length;
while(i--) { s+= a[i]; }
console.log('Bc=',s);
}
function Bd(a,s=0) {
let i=0;
do { s+= a[i] } while (++i < a.length);
console.log('Bd=',s);
}
function Be(a,s=0) {
let i=0; let n=a.length;
do { s+= a[i] } while (++i < n);
console.log('Be=',s);
}
function Bf(a,s=0) {
const it = a.values(); let e;
while (!(e = it.next()).done) { s+= e.value; }
console.log('Bf=',s);
}
function Ca(a,s=0) {
a.map(x => { s+=x });
console.log('Ca=',s);
}
function Cb(a,s=0) {
a.forEach(x => { s+=x });
console.log('Cb=',s);
}
function Cc(a,s=0) {
a.every(x => (s+=x,1) );
console.log('Cc=',s);
}
function Cd(a,s=0) {
a.filter(x => { s+=x } );
console.log('Cd=',s);
}
function Ce(a,s=0) {
a.reduce( (z,c) => { s+=c }, 0 );
console.log('Ce=',s);
}
function Cf(a,s=0) {
a.reduceRight( (z,c) => { s+=c }, 0 );
console.log('Cf=',s);
}
function Cg(a,s=0) {
a.some(x => { s+=x } );
console.log('Cg=',s);
}
function Ch(a,s=0) {
Array.from(a, x=> s+=x);
console.log('Cc=',s);
}
Aa(arr);
Ab(arr);
Ac(arr);
Ad(arr);
Ae(arr);
Ba(arr);
Bb(arr);
Bc(arr);
Bd(arr);
Be(arr);
Bf(arr);
Ca(arr);
Cb(arr);
Cc(arr);
Cd(arr);
Ce(arr);
Cf(arr);
Cg(arr);
Ch(arr);
<p style="color: red">This snippets only PRESENTS code used for benchmark - it not perform test itself</p>
跨浏览器结果
所有经过测试的浏览器的结果
包含10个元素的数组
Chrome的搜索结果。您可以在计算机here
上执行测试包含1.000.000个元素的数组
Chrome的搜索结果。您可以在计算机here
上执行测试答案 29 :(得分:1)
var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
console.log("Index" + index);
console.log("Element" + item);
})
答案 30 :(得分:1)
// Looping through arrays using foreach ES6 way
var data = new Array(1,2,3,4,5);
data.forEach((val,index) => {
console.log("index :",index); // index
console.log("value :", val); // value
});
答案 31 :(得分:1)
如果阵列数量庞大,则应使用iterators
来提高效率。迭代器是某些JavaScript集合(例如Map
,Set
,String
,Array
)的属性。甚至for..of
都使用 iterator
。
迭代器可让您一次使用列表中的项目,就好像它们是流一样,从而提高了效率。使迭代器与众不同的是它如何遍历集合。其他循环需要预先加载整个集合以便对其进行迭代,而迭代器仅需要知道集合中的当前位置。
您可以通过调用迭代器的next
方法来访问当前项目。下一个方法将返回当前项目的 value
和一个 boolean
,以指示您何时到达集合的末尾。以下是从数组创建迭代器的示例。
使用values()
这样的方法将常规数组转换为迭代器:
const myArr = [2,3,4]
let it = myArr.values();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
您还可以使用Symbol.iterator
将常规数组转换为迭代器,如下所示:
const myArr = [2,3,4]
let it = myArr[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
您还可以将常规array
转换为iterator
,如下所示:
let myArr = [8, 10, 12];
function makeIterator(array) {
var nextIndex = 0;
return {
next: function() {
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
};
};
var it = makeIterator(myArr);
console.log(it.next().value); // {value: 8, done: false}
console.log(it.next().value); // {value: 10, done: false}
console.log(it.next().value); // {value: 12, done: false}
console.log(it.next().value); // {value: undefined, done: true}
注意:
iterable
。在这种情况下,请使用for..in
,因为它可以使用键代替值。您可以阅读有关iteration protocol
here的更多信息。
答案 32 :(得分:0)
/* get all form */
document.querySelectorAll( "form" ).forEach( form => {
/* each form add onsubmit event */
form.addEventListener( "submit", event => {
event.preventDefault(); // return false
/* display it */
alert(event.target.action);
console.log(event.target);
} );
} );
<form action="form1.php" >
<input type="submit" value="Submit" />
</form>
<form action="form2.php" >
<input type="submit" value="Submit" />
</form>
<form action="form3.php" >
<input type="submit" value="Submit" />
</form>
答案 33 :(得分:0)
我来自python,发现这种方法更加清晰。
theArray是数组,实例是数组的元素
for(let instance of theArray)
{
console.log("The instance",instance);
}
或
for( instance in theArray)
{
console.log("The instance",instance);
}
比较:
theArray.forEach(function(instance) {
console.log(instance);
});
但是到了最后,他们俩都在做同一件事
答案 34 :(得分:0)
我认为for/of
是必经之路:
const arr = ['a', 'b', 'c'];
for (const v of arr) {
console.log(v); // Prints "a", "b", "c"
}
与for/in
不同,for/of
会跳过数组上的非数字属性。例如,如果您设置了arr.foo = 'test'
,则for (var v in arr)
将通过'foo'
键进行循环。
与forEach()
不同,for/of
不会跳过数组中的“空洞”。 const arr = ['a',, 'c']
是有效的JavaScript,仅第二个元素是“ hole”。该数组在功能上等效于['a', undefined, 'c']
。
答案 35 :(得分:0)
如果您想使用forEach()
,它会看起来像 -
theArray.forEach ( element => {
console.log(element);
});
如果您想使用for()
,它会看起来像 -
for(let idx = 0; idx < theArray.length; idx++){
let element = theArray[idx];
console.log(element);
}
答案 36 :(得分:-1)
在jQuery中使用 grep 函数,例如:
$.grep([0, 1, 2], function(n, i) {
return n > 0;
});