在JavaScript中逐个遍历数组

如何使用JavaScript遍历数组中的所有条目?

我以为是这样的:

forEach(instance in theArray)

theArray我的数组在哪里,但这似乎是不正确的。

GilJinJin2020/03/09 16:24:37

如果您有大量阵列,则应使用它iterators来提高效率。迭代器是一定的JavaScript集合的性质(如MapSetStringArray)。甚至,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 在此处了解更多信息

乐米亚2020/03/09 16:24:36

我知道这是一篇旧文章,并且已经有很多不错的答案。为了更加完整,我想我会使用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内置的香草味for循环相反,使用该功能有优缺点

优点

  • 易读
  • 易写性
  • 如果可用,angular.forEach将使用ES5 forEach循环。现在,我会去的利弊部分efficientcy,作为foreach循环是比for循环更慢。我将其作为专业人士提及是因为保持一致和标准化非常好。

考虑以下两个嵌套循环,它们执行的功能完全相同。假设我们有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
        }
    }
}

诚然,这是一个非常简单的假设的例子,但我已经写了三重嵌入使用第二种方法循环,这是非常难以阅读,并为此事写。

缺点

  • 效率。angular.forEach和原生forEach,对于这个问题,都这么多比正常情况下慢for循环....约90%的速度较慢因此,对于大型数据集,最好坚持使用本机for循环。
  • 没有中断,继续或返回支持。continue实际上是由“ 意外支持的,要在一个angular.forEach简单的return;语句中继续在函数中放置一条语句,例如angular.forEach(array, function(item) { if (someConditionIsTrue) return; });,它将使语句在该迭代中继续从函数中退出。这也是由于本机forEach既不支持break也不继续的事实

我敢肯定,还有其他各种利弊,请随时添加您认为合适的任何内容。我认为,最重要的是,如果您需要效率,请坚持使用本机for循环来满足您的循环需求。但是,如果您的数据集较小,并且为了交换可读性和可写性而放弃某种效率是可以的,那么一定要丢掉angular.forEach那个坏孩子。

米亚Eva2020/03/09 16:24:36

向后循环

我认为反向 for循环在这里值得一提:

for (var i = array.length; i--; ) {
     // process array[i]
}

优点:

  • 您不需要声明一个临时len变量,也不必array.length在每次迭代时都进行比较,这两者都可能需要一分钟的优化。
  • 以相反的顺序从DOM中删除兄弟姐妹通常更为有效(浏览器需要减少其内部数组中元素的移动。)
  • 如果修改数组而循环,在或索引后(例如取出或插入在一个项array[i]),那么前向循环将跳过该左移进入位置处的项目,或再处理这是个项向右移动。在传统的for循环中,您可以更新i以指向需要处理的下一个项目-1,但是简单地反转迭代方向通常是一个更简单更优雅的解决方案
  • 类似地,在修改或删除嵌套的 DOM元素时,反向处理可以避免错误例如,考虑在处理父节点的子节点之前修改其内部HTML。到子节点到达时,它将与DOM分离,在编写父节点的innerHTML时已被新创建的子节点替换。
  • 与其他可用选项相比它的键入和读取更短尽管它输给了ES6 forEach()for ... of

缺点:

  • 它以相反的顺序处理项目。如果您要根据结果构建新的数组,或在屏幕上打印内容,则自然相对于原始顺序反转输出
  • 重复将兄弟姐妹作为第一个孩子插入DOM以保持其顺序效率较低(浏览器将不得不保持正确的状态。)为了高效,有序地创建DOM节点,只需像往常一样循环并追加(并使用“文档片段”)即可。
  • 反向循环使初级开发人员感到困惑(根据您的前景,您可能会认为这是一种优势。)

我应该一直使用吗?

某些开发人员默认情况下使用反向for循环,除非有充分的理由进行向前循环。

尽管性能提升通常微不足道,但仍会引起尖叫:

“只需对列表中的每个商品都这样做,我不在乎订单!”

然而在实践中是实际的意图的可靠指标,因为它是从这些场合没有区别,当你对井井有条,真的需要循环反向。因此,实际上,将需要另一种构造来准确表达“不在乎”的意图,这在大多数语言(包括ECMAScript)中目前尚不可用,但可以称为forEachUnordered()

如果顺序无关紧要,并且效率是一个问题(在游戏或动画引擎的最内部循环中),则可以将反向for循环用作您的首选模式。只要记住,在现有代码看到反向for循环并不一定意味着顺序无关紧要!

最好使用forEach()

通常,对于更关注透明度和安全性的高级代码,我以前建议将其Array::forEach用作循环的默认模式(尽管这些天我更喜欢使用for..of)。优先于forEach反向循环的原因有:

  • 阅读起来更清晰。
  • 它表明不会在块内移动(这总是隐藏在long forwhileloop中的可能的惊喜)。
  • 它为您提供了关闭的自由范围。
  • 它减少了局部变量的泄漏以及与外部变量(和外部变量的突变)的意外冲突。

然后,当您在代码中看到反向for循环时,这表明它是有充分原因(也许是上述原因之一)被反向的。看到传统的forward for循环可能表明可以进行移位。

(如果对意图的讨论对您没有意义,那么您和您的代码可能会受益于观看Crockford关于“ 编程风格和大脑”的讲座。)

现在,使用它甚至更好。

有一个关于是否辩论for..of或者forEach()是较好的:

  • 为了最大程度地支持浏览器,for..of 需要为迭代器使用polyfill,从而使您的应用执行速度稍慢,下载速度稍大。

  • 因此(并鼓励使用mapfilter),一些前端样式指南for..of完全禁止使用

  • 但是上述问题不适用于for..of现在已得到很好支持的Node.js应用程序

  • 而且在内部await 不起作用forEach()在这种情况下,使用for..of最清晰的模式

就个人而言,我倾向于使用最容易阅读的外观,除非性能或尺寸缩小已成为主要问题。因此,这些天我更喜欢使用for..of而不是forEach(),但是在适用时,我将始终使用mapfilterfindsome(为了我的同事,我很少使用reduce。)


它是如何工作的?

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从而避免了数组越界 undefined项的任何问题

  • 为什么它在索引0之前不停止迭代?

    当条件i--评估为假值时(当它产生0时),循环将停止迭代

    诀窍在于,与不同--i,尾随的i--运算符会递减,i但会在递减之前产生值您的控制台可以证明这一点:

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    因此,在最后一次迭代中,以前是1i--表达式将其更改为0,但实际上产生了1(真实),因此条件通过了。在下一次迭代中,i--i更改-1,但产生0(假),从而导致执行立即退出循环的底部。

    在传统的for循环中,i++并且++i可以互换(正如Douglas Crockford指出的那样)。但是在相反的for循环中,因为我们的减量也是我们的条件表达式,所以i--如果要处理索引0的项,则必须坚持


琐事

有些人喜欢在反向for循环中画一个小箭头,并以眨眼结束:

for (var i = array.length; i --> 0 ;) {

感谢WYL向我展示反向for循环的好处和恐惧。

小小小胖2020/03/09 16:24:35

如果您使用的是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].
}
小哥Stafan2020/03/09 16:17:50

Lambda语法通常在Internet Explorer 10或更低版本中不起作用。

我通常使用

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

如果您是jQuery 爱好者并且已经在运行jQuery文件,则应反转index和value参数的位置

$("#ul>li").each(function(**index, value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
猪猪小卤蛋2020/03/09 16:17:50

根据新的更新功能ECMAScript 6(ES6)和ECMAScript 2015,您可以在循环中使用以下选项:

for循环

for(var i = 0; i < 5; i++){
  console.log(i);
}

// Output: 0,1,2,3,4

for ...在循环中

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

做... while循环

let x = 0

do{
  console.log(x)
  x++
}while(x < 5)

// Output: 1,2,3,4
D坤2020/03/09 16:17:49

如果要使用forEach(),它将看起来像-

theArray.forEach ( element => {
    console.log(element);
});

如果要使用for(),它将看起来像-

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}
GilJinJin2020/03/09 16:17:49

如果您有大量阵列,则应使用它iterators来提高效率。迭代器是一定的JavaScript集合的性质(如MapSetStringArray)。甚至,for..of使用iterator在引擎罩。

Iterators improve efficiency by letting you consume the items in a list one at a time as if they were a stream. What makes an iterator special is how it traverses a collection. Other loops need to load the entire collection up front in order to iterate over it, whereas an iterator only needs to know the current position in the collection.

You access the current item by calling the iterator’s next method. The next method will return the value of the current item and a boolean to indicate when you have reached the end of the collection. The following is an example of creating an iterator from an array.

Transform your regular array to iterator using values() method like this:

    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 在此处了解更多信息

神无神无2020/03/09 16:17:49

您可以这样调用forEach:

forEach将遍历您提供的数组,并且每次迭代都将element保留该迭代的值。如果需要索引,可以通过将ifor作为每个回调函数的第二个参数传递来获取当前索引

Foreach基本上是一个高阶函数,它将另一个函数作为其参数。

let theArray= [1,3,2];

theArray.forEach((element) => {
  // Use the element of the array
  console.log(element)
}

输出:

1
3
2

您也可以像这样遍历数组:

for (let i=0; i<theArray.length; i++) {
  console.log(i); // i will have the value of each index
}
Davaid小宇宙2020/03/09 16:17:49

最接近您的想法的方法是使用Array.forEach()接受将对数组的每个元素执行的闭包函数。

myArray.forEach(
  (item) => {
    // Do something
    console.log(item);
  }
);

另一种可行的方法是使用Array.map()以相同的方式工作的方法,但是它还会使用您返回的所有值,并将它们返回到新数组中(基本上将每个元素映射到一个新元素),如下所示:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
JinJin小卤蛋2020/03/09 16:17:49

您可以使用:

  1. 每次

    theArray.forEach(function (array, index) {
        console.log(index);
        console.log(array);
    });
    
  2. 对于

    for(var i=0; i<theArray.length; i++) {
        console.log(i)
    }
    
  3. 地图

    theArray.map(x => console.log(x));
    
  4. 地图

    theArray.filter(x => console.log(x));
    

还有很多其他需要迭代的地方。

逆天Eva2020/03/09 16:17:49

jQuery的使用方式$.map

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];
达蒙老丝2020/03/09 16:17:49

我也想将其添加为反向循环的组成部分,并在上面为也希望使用此语法的人提供答案。

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

优点:

这样做的好处是:您已经在第一个引用中已经有了引用,以后无需在另一行声明它。在对象数组中循环时很方便。

缺点:

每当引用为假-假(未定义等)时,这都会中断。但是,它可以用作优势。但是,这会使阅读起来有些困难。而且还可以根据浏览器进行“非”优化,使其比原始浏览器更快地工作。

梅Davaid2020/03/09 16:17:49

没有内置的闯入能力forEach要中断执行,请使用Array#some以下代码:

[1,2,3].some(function(number) {
    return number === 1;
});

之所以some可行,是因为一旦按数组顺序执行的任何回调均返回true,则返回true,从而使其余部分的执行短路。 原来的答案 参见数组原型一些

LEYJim2020/03/09 16:17:49

几种方法可以遍历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>

do / while-在条件为true的情况下也循环遍历代码块,至少运行一次

var text = ""
var i = 0;

do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);

document.getElementById("example").innerHTML = text;
<p id="example"></p>

功能循环 - ,forEachmapfilterreduce(他们遍历功能,但是它们如果你需要做的事情与你的阵列等使用

// 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>

有关数组上函数编程的更多信息和示例,请参阅博客文章JavaScript中函数编程:map,filter和reduce

StafanItachi2020/03/09 16:17:49

for eachJavaScript中没有任何循环您可以使用库来获得此功能(我建议使用Underscore.js),也可以使用简单的forin循环。

for (var instance in objects) {
   ...
}

但是,请注意,可能有理由使用更简单的for循环(请参阅堆栈溢出问题,为什么在数组迭代中使用“ for…in”是一个坏主意?

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
Itachi猪猪2020/03/09 16:17:49

从ECMAScript 6开始:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

where of避免与之关联的怪异之处,in并使其像for任何其他语言循环一样工作,并且在循环内let绑定i而不是在函数内绑定

{}当只有一个命令时(例如,在以上示例中),可以省略大括号()。

Green猿古一2020/03/09 16:17:49

现在,一个简单的解决方案是使用underscore.js库它提供了许多有用的工具,例如each和将自动将作业委派给本机(forEach如果可用)。

CodePen如何工作的示例是:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

也可以看看

凯神无2020/03/09 16:17:49

有三种实现方式foreach的jQuery如下。

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
Near路易小胖2020/03/09 16:17:49

如果您不介意清空数组:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x将包含的最后一个值,y并将其从数组中删除。您还可以使用来shift()从中提供和删除第一项y

小小西门2020/03/09 16:17:49

如果要遍历数组,请使用标准的三部分for循环。

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

您可以通过myArray.length向后缓存或对其进行迭代来获得一些性能优化

Davaid番长十三2020/03/09 16:17:49

一些C风格的语言用于foreach遍历枚举。在JavaScript中,这是通过for..in循环结构完成的

var index,
    value;
for (index in obj) {
    value = obj[index];
}

有一个陷阱。for..in将遍历对象的每个可枚举成员,以及其原型上的成员。为了避免读取通过对象原型继承的值,只需检查属性是否属于对象:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

此外,ECMAScript 5添加了一种forEach方法Array.prototype,可以使用回溯方法对数组进行枚举(polyfill在文档中,因此您仍可以将其用于较旧的浏览器):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

重要的是要注意,Array.prototype.forEach回调返回时不会中断falsejQueryUnderscore.js提供了它们自己的变体,each以提供可以短路的循环。

番长西里神无2020/03/09 16:17:49

If you’re using the jQuery library, you can use jQuery.each:

$.each(yourArray, function(index, value) {
  // do your stuff here
});

EDIT :

As per question, user want code in javascript instead of jquery so the edit is

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
LEY蛋蛋Near2020/03/09 16:17:49

注意:此答案已过时。对于更现代的方法,请查看array上可用的方法感兴趣的方法可能是:

  • 每次
  • 地图
  • 过滤
  • 压缩
  • 降低
  • 每一个
  • 一些

迭代的标准方式在阵列中的JavaScript是香草for-loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

但是请注意,这种方法仅在数组密集且每个索引都被一个元素占用的情况下才有用。如果数组稀疏,则使用此方法会遇到性能问题,因为您将遍历数组中实际上存在的许多索引在这种情况下,for .. in-loop可能是一个更好的主意。但是,您必须使用适当的防护措施来确保仅对数组的所需属性(即数组元素)进行操作,因为for..in-loop还将在旧版浏览器中枚举,或者如果其他属性定义为enumerable

ECMAScript 5中,数组原型上将有一个forEach方法,但是旧版浏览器不支持该方法。因此,要能够始终如一地使用它,您必须具有一个支持它的环境(例如,用于服务器端JavaScript的Node.js),或使用“ Polyfill”。但是,用于此功能的Polyfill很简单,并且由于它使代码更易于阅读,因此可以很好地包含它。

猪猪小卤蛋2020/03/09 12:31:54

根据新的更新功能ECMAScript 6(ES6)和ECMAScript 2015,您可以在循环中使用以下选项:

for循环

for(var i = 0; i < 5; i++){
  console.log(i);
}

// Output: 0,1,2,3,4

for ...在循环中

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

做... while循环

let x = 0

do{
  console.log(x)
  x++
}while(x < 5)

// Output: 1,2,3,4
D坤2020/03/09 12:31:54

如果要使用forEach(),它将看起来像-

theArray.forEach ( element => {
    console.log(element);
});

如果要使用for(),它将看起来像-

for(let idx = 0; idx < theArray.length; idx++){
    let element = theArray[idx];
    console.log(element);
}
JinJin小卤蛋2020/03/09 12:31:54

您可以使用:

  1. 每次

    theArray.forEach(function (array, index) {
        console.log(index);
        console.log(array);
    });
  2. 对于

    for(var i=0; i<theArray.length; i++) {
        console.log(i)
    }
  3. 地图

    theArray.map(x => console.log(x));
  4. 地图

    theArray.filter(x => console.log(x));

还有很多其他需要迭代的地方。

GilJinJin2020/03/09 12:31:54

如果您有大量阵列,则应使用它iterators来提高效率。迭代器是一定的JavaScript集合的性质(如MapSetStringArray)。甚至,for..of使用iterator在引擎罩。

Iterators improve efficiency by letting you consume the items in a list one at a time as if they were a stream. What makes an iterator special is how it traverses a collection. Other loops need to load the entire collection up front in order to iterate over it, whereas an iterator only needs to know the current position in the collection.

You access the current item by calling the iterator’s next method. The next method will return the value of the current item and a boolean to indicate when you have reached the end of the collection. The following is an example of creating an iterator from an array.

Transform your regular array to iterator using values() method like this:

    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 在此处了解更多信息

小哥Stafan2020/03/09 12:31:54

Lambda语法通常在Internet Explorer 10或更低版本中不起作用。

我通常使用

[].forEach.call(arrayName,function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});

如果您是jQuery 爱好者并且已经在运行jQuery文件,则应反转index和value参数的位置

$("#ul>li").each(function(**index, value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});
神无神无2020/03/09 12:31:54

您可以这样调用forEach:

forEach将遍历您提供的数组,并且每次迭代都将element保留该迭代的值。如果需要索引,可以通过将ifor作为每个回调函数的第二个参数传递来获取当前索引

Foreach基本上是一个高阶函数,它将另一个函数作为其参数。

let theArray= [1,3,2];

theArray.forEach((element) => {
  // Use the element of the array
  console.log(element)
}

输出:

1
3
2

您也可以像这样遍历数组:

for (let i=0; i<theArray.length; i++) {
  console.log(i); // i will have the value of each index
}
Davaid小宇宙2020/03/09 12:31:54

最接近您的想法的方法是使用Array.forEach()接受将对数组的每个元素执行的闭包函数。

myArray.forEach(
  (item) => {
    // Do something
    console.log(item);
  }
);

另一种可行的方法是使用Array.map()以相同的方式工作的方法,但是它还会使用您返回的所有值,并将它们返回到新数组中(基本上将每个元素映射到一个新元素),如下所示:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]
逆天Eva2020/03/09 12:31:54

jQuery的使用方式$.map

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];
达蒙老丝2020/03/09 12:31:54

我也想将其添加为反向循环的组成部分,并在上面为也希望使用此语法的人提供答案。

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

优点:

这样做的好处是:您已经在第一个引用中已经有了引用,以后无需在另一行声明它。在对象数组中循环时很方便。

缺点:

每当引用为假-假(未定义等)时,这都会中断。但是,它可以用作优势。但是,这会使阅读起来有些困难。而且还可以根据浏览器进行“非”优化,使其比原始浏览器更快地工作。

梅Davaid2020/03/09 12:31:54

没有内置的闯入能力forEach要中断执行,请使用Array#some以下代码:

[1,2,3].some(function(number) {
    return number === 1;
});

之所以some可行,是因为一旦按数组顺序执行的任何回调均返回true,则返回true,从而使其余部分的执行短路。 原来的答案 参见数组原型一些

LEYJim2020/03/09 12:31:54

几种方法可以遍历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>

do / while-在条件为true的情况下也循环遍历代码块,至少运行一次

var text = ""
var i = 0;

do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);

document.getElementById("example").innerHTML = text;
<p id="example"></p>

功能循环 - ,forEachmapfilterreduce(他们遍历功能,但是它们如果你需要做的事情与你的阵列等使用

// 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>

有关数组上函数编程的更多信息和示例,请参阅博客文章JavaScript中函数编程:map,filter和reduce

StafanItachi2020/03/09 12:31:54

for eachJavaScript中没有任何循环您可以使用库来获得此功能(我建议使用Underscore.js),也可以使用简单的forin循环。

for (var instance in objects) {
   ...
}

但是,请注意,可能有理由使用更简单的for循环(请参阅堆栈溢出问题,为什么在数组迭代中使用“ for…in”是一个坏主意?

var instance;
for (var i=0; i < objects.length; i++) {
    var instance = objects[i];
    ...
}
Green猿古一2020/03/09 12:31:53

现在,一个简单的解决方案是使用underscore.js库它提供了许多有用的工具,例如each和将自动将作业委派给本机(forEach如果可用)。

CodePen如何工作的示例是:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

也可以看看

Itachi猪猪2020/03/09 12:31:53

从ECMAScript 6开始:

list = [0, 1, 2, 3]
for (let obj of list) {
    console.log(obj)
}

where of避免与之关联的怪异之处,in并使其像for任何其他语言循环一样工作,并且在循环内let绑定i而不是在函数内绑定

{}当只有一个命令时(例如,在以上示例中),可以省略大括号()。

Near路易小胖2020/03/09 12:31:53

如果您不介意清空数组:

var x;

while(x = y.pop()){ 

    alert(x); //do something 

}

x将包含的最后一个值,y并将其从数组中删除。您还可以使用来shift()从中提供和删除第一项y

乐米亚2020/03/09 12:31:53

我知道这是一篇旧文章,并且已经有很多不错的答案。为了更加完整,我想我会使用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内置的香草味for循环相反,使用该功能有优缺点

优点

  • 易读
  • 易写性
  • 如果可用,angular.forEach将使用ES5 forEach循环。现在,我会去的利弊部分efficientcy,作为foreach循环是比for循环更慢。我将其作为专业人士提及是因为保持一致和标准化非常好。

考虑以下两个嵌套循环,它们执行的功能完全相同。假设我们有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
        }
    }
}

诚然,这是一个非常简单的假设的例子,但我已经写了三重嵌入使用第二种方法循环,这是非常难以阅读,并为此事写。

缺点

  • 效率。angular.forEach和原生forEach,对于这个问题,都这么多比正常情况下慢for循环....约90%的速度较慢因此,对于大型数据集,最好坚持使用本机for循环。
  • 没有中断,继续或返回支持。continue实际上是由“ 意外支持的,要在一个angular.forEach简单的return;语句中继续在函数中放置一条语句,例如angular.forEach(array, function(item) { if (someConditionIsTrue) return; });,它将使语句在该迭代中继续从函数中退出。这也是由于本机forEach既不支持break也不继续的事实

我敢肯定,还有其他各种利弊,请随时添加您认为合适的任何内容。我认为,最重要的是,如果您需要效率,请坚持使用本机for循环来满足您的循环需求。但是,如果您的数据集较小,并且为了交换可读性和可写性而放弃某种效率是可以的,那么一定要丢掉angular.forEach那个坏孩子。

凯神无2020/03/09 12:31:53

有三种实现方式foreach的jQuery如下。

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
小小西门2020/03/09 12:31:53

如果要遍历数组,请使用标准的三部分for循环。

for (var i = 0; i < myArray.length; i++) {
    var arrayItem = myArray[i];
}

您可以通过myArray.length向后缓存或对其进行迭代来获得一些性能优化

LEY蛋蛋Near2020/03/09 12:31:53

注意:此答案已过时。对于更现代的方法,请查看array上可用的方法感兴趣的方法可能是:

  • 每次
  • 地图
  • 过滤
  • 压缩
  • 降低
  • 每一个
  • 一些

迭代的标准方式在阵列中的JavaScript是香草for-loop:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element
}

但是请注意,这种方法仅在数组密集且每个索引都被一个元素占用的情况下才有用。如果数组稀疏,则使用此方法会遇到性能问题,因为您将遍历数组中实际上存在的许多索引在这种情况下,for .. in-loop可能是一个更好的主意。但是,您必须使用适当的防护措施来确保仅对数组的所需属性(即数组元素)进行操作,因为for..in-loop还将在旧版浏览器中枚举,或者如果其他属性定义为enumerable

ECMAScript 5中,数组原型上将有一个forEach方法,但是旧版浏览器不支持该方法。因此,要能够始终如一地使用它,您必须具有一个支持它的环境(例如,用于服务器端JavaScript的Node.js),或使用“ Polyfill”。但是,用于此功能的Polyfill很简单,并且由于它使代码更易于阅读,因此可以很好地包含它。

逆天西门2020/03/09 12:31:53

If you’re using the jQuery library, you can use jQuery.each:

$.each(yourArray, function(index, value) {
  // do your stuff here
});

EDIT :

As per question, user want code in javascript instead of jquery so the edit is

var length = yourArray.length;   
for (var i = 0; i < length; i++) {
  // Do something with yourArray[i].
}
Davaid番长十三2020/03/09 12:31:53

一些C风格的语言用于foreach遍历枚举。在JavaScript中,这是通过for..in循环结构完成的

var index,
    value;
for (index in obj) {
    value = obj[index];
}

有一个陷阱。for..in将遍历对象的每个可枚举成员,以及其原型上的成员。为了避免读取通过对象原型继承的值,只需检查属性是否属于对象:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

此外,ECMAScript 5添加了一种forEach方法Array.prototype,可以使用回溯方法对数组进行枚举(polyfill在文档中,因此您仍可以将其用于较旧的浏览器):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

重要的是要注意,Array.prototype.forEach回调返回时不会中断falsejQueryUnderscore.js提供了它们自己的变体,each以提供可以短路的循环。