For-each over an array in JavaScript?
如何使用javascript循环遍历数组中的所有条目?
我以为是这样的:
1 | forEach(instance in theArray) |
其中
假设您想在
1 2 3 | Array.prototype.forEach.call(node.childNodes, function(child) { // Do something with `child` }); |
如果要经常这样做,可能需要将函数引用的副本抓取到变量中以便重用,例如:好的。
1 2 3 4 5 6 7 | // (This is all presumably in some scoping function) var forEach = Array.prototype.forEach; // Then later... forEach.call(node.childNodes, function(child) { // Do something with `child` }); |
使用一个简单的
显然,一个简单的
正确使用
与阵列具有相同安全保护的
使用
显式使用迭代器(ES2015+)好的。
看4,我们要看看迭代器是如何发挥作用的。好的。
创建真数组
有时,您可能希望将类似数组的对象转换为真正的数组。这样做非常容易:好的。
使用数组的
我们可以使用数组的
1 | var trueArray = Array.prototype.slice.call(arrayLikeObject); |
例如,如果我们想将一个
1 | var divs = Array.prototype.slice.call(document.querySelectorAll("div")); |
请参见下面主机提供的对象的警告。特别要注意,在IE8和更早版本中,这将失败,因为它不允许您将宿主提供的对象用作这样的
使用排列语法(
还可以在支持此功能的JavaScript引擎中使用ES2015的Spread语法:好的。
1 | var trueArray = [...iterableObject]; |
例如,如果我们想将
1 | var divs = [...document.querySelectorAll("div")]; |
使用
1 | var divs = Array.from(document.querySelectorAll("div")); |
或者,如果要获取具有给定类的元素的标记名数组,可以使用mapping函数:好的。
1 2 3 4 5 6 7 | // Arrow function (ES2015): var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName); // Standard function (since `Array.from` can be shimmed): var divs = Array.from(document.querySelectorAll(".some-class"), function(element) { return element.tagName; }); |
主机提供对象的警告
如果将
Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that
[[Get]] and[[Put]] for a particular host object indeed fetch and store property values but[[HasProperty]] always generates false.Ok.
(我在ES2015规范中找不到相同的措辞,但肯定仍然如此。)同样,在撰写本文时,公共主机在现代浏览器中提供了类似数组的对象[例如,
DR好的。
- 不要使用
for-in ,除非你使用它时有安全措施或者至少知道它为什么会咬你。 你最好的赌注通常是好的。
- 一个
for-of 环路(仅限ES2015+ Array#forEach (spec MDN (或其亲属some 等)(仅限es5+)- 一个简单的老式的
for 循环, - 或有防护措施的
for-in 。
- 一个
但是还有很多东西需要探索,继续阅读…好的。
javascript具有强大的语义,可以循环遍历数组和类似数组的对象。我将答案分为两部分:用于真正数组的选项,以及用于类似于数组的对象的选项,例如
我会很快注意到,通过将ES2015扩展到ES5,您现在可以使用ES2015选项,甚至在ES5引擎上也是如此。搜索"ES2015蒸腾"/"ES6蒸腾"了解更多…好的。
好吧,让我们看看我们的选择:好的。对于实际数组
EcmaScript 5("ES5")中有三个选项,是目前最广泛支持的版本,在EcmaScript 2015("ES2015","ES6")中又增加了两个选项:好的。
细节:好的。1。使用
在任何模糊的现代环境中(因此,不是IE8),您可以使用ES5(直接或使用polyfills)添加的
1 2 3 4 | var a = ["a","b","c"]; a.forEach(function(entry) { console.log(entry); }); |
好的。
除非您支持像IE8这样过时的浏览器(截至2016年9月的这篇文章中,netaps的市场份额刚刚超过4%),否则您可以在通用网页中愉快地使用
如果您担心对每个数组条目进行函数调用的运行时开销,请不要担心;详细信息。好的。
此外,
every (回调第一次返回false 或错误时停止循环)some (在回调第一次返回true 或其他真实的东西时停止循环)filter (创建一个新的数组,包括过滤函数返回true 的元素,省略返回false 的元素)map (根据回调返回的值创建一个新数组)reduce (通过反复调用回调、传递以前的值来建立一个值;有关详细信息,请参阅规范;用于汇总数组内容和许多其他内容)reduceRight (如reduce ,但按降序而不是升序工作)
2。使用一个简单的
有时旧方法是最好的:好的。
1 2 3 4 5 | var index; var a = ["a","b","c"]; for (index = 0; index < a.length; ++index) { console.log(a[index]); } |
好的。
如果数组的长度在循环过程中不会改变,而且是在性能敏感的代码中(不太可能),那么在前面捕获长度的稍微复杂一点的版本可能会快一点:好的。
1 2 3 4 5 | var index, len; var a = ["a","b","c"]; for (index = 0, len = a.length; index < len; ++index) { console.log(a[index]); } |
好的。
和/或倒数:好的。
1 2 3 4 5 | var index; var a = ["a","b","c"]; for (index = a.length - 1; index >= 0; --index) { console.log(a[index]); } |
好的。
但是使用现代的JavaScript引擎,你很少需要补充最后一点内容。好的。
在ES2015及更高版本中,您可以将索引和值变量设置为
1 2 3 4 5 6 7 | let a = ["a","b","c"]; for (let index = 0; index < a.length; ++index) { let value = a[index]; console.log(index, value); } //console.log(index); // would cause"ReferenceError: index is not defined" //console.log(value); // would cause"ReferenceError: value is not defined" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | let a = ["a","b","c"]; for (let index = 0; index < a.length; ++index) { let value = a[index]; console.log(index, value); } try { console.log(index); } catch (e) { console.error(e); //"ReferenceError: index is not defined" } try { console.log(value); } catch (e) { console.error(e); //"ReferenceError: value is not defined" } |
好的。
当您这样做时,不仅为每个循环迭代重新创建
1 2 3 4 5 6 | let divs = document.querySelectorAll("div"); for (let index = 0; index < divs.length; ++index) { divs[index].addEventListener('click', e => { console.log("Index is:" + index); }); } |
1 2 3 4 5 6 | let divs = document.querySelectorAll("div"); for (let index = 0; index < divs.length; ++index) { divs[index].addEventListener('click', e => { console.log("Index is:" + index); }); } |
1 2 3 4 5 | zero one two three four |
好的。
如果你有五个div,如果你点击第一个,你会得到"index is:0",如果你点击最后一个,你会得到"index is:4"。如果您使用
你会得到人们告诉你使用
阵列上
- 它是一个稀疏的阵列,其中有巨大的间隙,或者
- 您正在使用非元素属性,并且希望将它们包含在循环中
仅查看第一个示例:如果使用适当的保护措施,则可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // `a` is a sparse array var key; var a = []; a[0] ="a"; a[10] ="b"; a[10000] ="c"; for (key in a) { if (a.hasOwnProperty(key) && // These checks are /^0$|^[1-9]\d*$/.test(key) && // explained key <= 4294967294 // below ) { console.log(a[key]); } } |
好的。
注意这三项检查:好的。
对象具有该名称的自身属性(不是从原型继承的属性),以及好的。
该键是所有十进制数字(例如,普通字符串形式,而不是科学记数法),以及好的。
当强制为数字时,键的值<=2^32-2(即4294967294)。那个号码是从哪里来的?它是规范中数组索引定义的一部分。其他数字(非整数、负数、大于2^32-2的数字)不是数组索引。之所以是2^32-2,是因为它使最大的索引值小于2^32-1,这是数组的
当然,在内联代码中不会这样做。你可以写一个实用函数。也许:好的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | // Utility function for antiquated environments without `forEach` var hasOwn = Object.prototype.hasOwnProperty; var rexNum = /^0$|^[1-9]\d*$/; function sparseEach(array, callback, thisArg) { var index; for (var key in array) { index = +key; if (hasOwn.call(a, key) && rexNum.test(key) && index <= 4294967294 ) { callback.call(thisArg, array[key], index, array); } } } var a = []; a[5] ="five"; a[10] ="ten"; a[100000] ="one hundred thousand"; a.b ="bee"; sparseEach(a, function(value, index) { console.log("Value at" + index +" is" + value); }); |
好的。4。使用
ES2015为javascript添加了迭代器。使用迭代器的最简单方法是新的
1 2 3 4 | const a = ["a","b","c"]; for (const val of a) { console.log(val); } |
好的。
在封面下,它从数组中获取一个迭代器并循环遍历它,从中获取值。这并没有使用
有时,您可能需要显式地使用迭代器。你也可以这样做,尽管它比
1 2 3 4 5 6 | const a = ["a","b","c"]; const it = a.values(); let entry; while (!(entry = it.next()).done) { console.log(entry.value); } |
好的。
迭代器是与规范中的迭代器定义匹配的对象。它的
- 以东十一〔21〕这是我上面用过的。它返回一个迭代器,其中每个
value 都是该迭代的数组条目(前面例子中的"a" 、"b" 和"c" )。 keys() :返回一个迭代器,其中每个value 是该迭代的关键(因此对于上面的a ,它是"0" ,然后是"1" ,然后是"2" 。entries() :返回一个迭代器,其中每个value 都是该迭代的[key, value] 形式的数组。
对于类似数组的对象
除了真数组之外,还有类似数组的对象,它们具有
上面提到的数组方法中,至少有一部分(可能是大部分甚至全部)经常同样适用于类似数组的对象:好的。
使用
编辑:这个答案完全过时了。要获得更现代的方法,请查看数组上可用的方法。感兴趣的方法可能是:
- 前额
- 地图
- 滤波器
- 拉链
- 减少
- 每一个
- 一些
在javascript中迭代数组的标准方法是一个普通的
1 2 3 4 5 6 | var length = arr.length, element = null; for (var i = 0; i < length; i++) { element = arr[i]; // Do something with element } |
但是,请注意,只有当您有一个密集的数组,并且每个索引都被一个元素占据时,这种方法才是好的。如果数组是稀疏的,那么使用这种方法可能会遇到性能问题,因为您将迭代数组中不存在的大量索引。在这种情况下,一个
在ECMAScript 5中,数组原型上将有一个foreach方法,但在传统浏览器中不支持它。因此,为了能够始终如一地使用它,您必须拥有支持它的环境(例如,node.js用于服务器端的javascript),或者使用"polyfill"。然而,此功能的polyfill非常简单,因为它使代码更容易阅读,所以它是一个很好的polyfill。
如果您使用的是jquery库,则可以使用jquery.each:
1 2 3 | $.each(yourArray, function(index, value) { // do your stuff here }); |
编辑:
根据问题,用户希望使用javascript而不是jquery进行代码编辑,因此
1 2 3 4 | var length = yourArray.length; for (var i = 0; i < length; i++) { // Do something with yourArray[i]. } |
向后循环
我认为倒循环值得一提:好的。
1 2 3 | for (var i = array.length; i--; ) { // process array[i] } |
优势:
- 您不需要声明一个临时的
len 变量,也不需要在每次迭代中与array.length 进行比较,这两种方法都可能是一分钟的优化。 - 以相反的顺序从DOM中删除兄弟姐妹通常更有效。(浏览器需要减少内部数组中元素的移动。)
- 如果在循环时修改数组,在索引i处或索引i之后(例如,在
array[i] 处删除或插入一个项),则前循环将跳过向左移动到位置i的项,或重新处理向右移动的第i个项。在传统的for循环中,您可以更新i以指向下一个需要处理的项-1,但是简单地反转迭代的方向通常是一个更简单和更优雅的解决方案。 - 同样,在修改或删除嵌套的DOM元素时,反向处理可以避免错误。例如,在处理父节点的子节点之前,请考虑修改父节点的innerhtml。当到达子节点时,它将从DOM中分离出来,在编写父节点的innerhtml时被新创建的子节点替换。
- 它的输入和读取比其他一些可用选项要短。虽然输给了埃多克斯1〔3〕和埃斯6的埃多克斯1〔4〕。
缺点:
- 它按相反的顺序处理项目。如果您正在根据结果构建一个新的数组,或者在屏幕上打印内容,那么输出自然会与原始顺序相反。
- 重复地将兄弟姐妹作为第一个子级插入到DOM中以保持其顺序的效率较低。(浏览器必须不断地调整方向。)为了高效有序地创建DOM节点,只需按正常方式向前循环和追加(也可以使用"文档片段")。
- 对于初级开发人员来说,反向循环是令人困惑的。(你可能认为这是一个优势,取决于你的前景。)
我应该一直使用它吗?
有些开发人员默认使用反向for循环,除非有充分的理由向前循环。好的。
虽然性能提升通常是微不足道的,但它有点尖叫:好的。
"Just do this to every item in the list, I don't care about the order!"
Ok.
然而,在实践中,这实际上并不是一个意图的可靠指示,因为它与那些你关心秩序的场合是不可区分的,而且确实需要反向循环。因此,实际上,需要另一个构造来准确地表达"不在乎"的意图,这是目前大多数语言(包括ecmascript)都不可用的,但可以称为
如果顺序无关紧要,并且效率是一个问题(在游戏或动画引擎的最里面的循环中),那么使用reverse for loop作为进入模式可能是可以接受的。请记住,在现有代码中看到循环的反转并不一定意味着顺序不相关!好的。最好使用foreach()。
一般来说,对于更高级别的代码,如果更关注清晰度和安全性,我建议使用
- 看书很清楚。
- 它表明我不会在块内移动(这在长的
for 和while 循环中总是一个可能的惊喜)。 - 它为闭包提供了一个自由的空间。
- 它减少了局部变量的泄漏和与外部变量的意外碰撞(和突变)。
然后,当您在代码中看到reverse for loop时,这是一个提示,它是出于一个很好的原因(可能是上面描述的其中一个原因)而被反转的。而看到传统的"向前-向前"循环可能表明发生了变化。好的。
(如果对意图的讨论对您没有意义,那么您和您的代码可能会受益于观看Crockford关于编程风格和您的大脑的演讲。)好的。它是如何工作的?
1 2 3 | for (var i = 0; i < array.length; i++) { ... } // Forwards for (var i = array.length; i--; ) { ... } // Reverse |
您会注意到,
它如何在不爆炸的情况下从
array.length 开始?好的。因为
i-- 在每次迭代之前运行,所以在第一次迭代时,我们实际上将访问array.length - 1 处的项目,这避免了与array out of boundsundefined 项目有关的任何问题。好的。为什么不在索引0之前停止迭代?好的。
当条件
i-- 计算为假值(当它产生0时)时,循环将停止迭代。好的。诀窍是,与
--i 不同,后面的i-- 操作符减少i ,但在减少之前生成值。您的控制台可以演示:好的。> var i = 5; [i, i--, i]; 好的。[5, 5, 4] 好的。所以在最后一次迭代中,我以前是1,
i-- 表达式将其更改为0,但实际上生成1(truthy),所以条件通过了。在下一个迭代中,i-- 将i更改为-1,但生成0(错误),导致执行立即从循环底部退出。好的。在传统的for loop中,
i++ 和++i 可以互换(正如道格拉斯·克罗克福德指出的那样)。但是在相反的for循环中,由于减量也是我们的条件表达式,因此如果我们想处理索引0处的项,必须坚持使用i-- 。好的。
琐事
有些人喜欢在反向的
1 | for (var i = array.length; i --> 0 ;) { |
学分归Wyl,因为它向我展示了反向for循环的好处和恐怖之处。好的。好啊。
一些C语言使用
1 2 3 4 5 | var index, value; for (index in obj) { value = obj[index]; } |
有一个陷阱。
1 2 3 4 5 | for (i in obj) { if (obj.hasOwnProperty(i)) { //do stuff } } |
另外,ecmascript 5在
1 2 3 | arr.forEach(function (val, index, theArray) { //do stuff }); |
需要注意的是,当回调返回
如果要在数组上循环,请使用标准的三部分
1 2 3 | for (var i = 0; i < myArray.length; i++) { var arrayItem = myArray[i]; } |
您可以通过缓存
我知道这是一个古老的帖子,已经有很多好的答案了。为了更完整一点,我想我会用安古拉吉斯加上另一个。当然,这只适用于使用角的情况,显然,尽管如此,我还是想说。
有不同的方法可以使用角度的前臂环。最简单和可能最常用的是
1 2 3 4 5 | var temp = [1, 2, 3]; angular.forEach(temp, function(item) { //item will be each element in the array //do something }); |
另一种将项从一个数组复制到另一个数组的方法是
1 2 3 4 5 | 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); |
不过,您不必这样做,您只需执行以下操作,这相当于前面的示例:
1 2 3 | angular.forEach(temp, function(item) { temp2.push(item); }); |
现在,与内置香草味的
赞成的意见
- 易于阅读
- 易于书写
- 如果可用,
angular.forEach 将使用es5 foreach循环。现在,我将在cons部分中讨论效率,因为foreach循环比for循环慢得多。我说这是一个专业人士,因为它是很好的一致性和标准化。
考虑下面的两个嵌套循环,它们执行完全相同的操作。假设我们有两个对象数组,每个对象包含一个结果数组,每个结果数组都有一个字符串(或其他)的值属性。假设我们需要迭代每个结果,如果它们相等,那么执行一些操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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%。因此,对于大型数据集,最好坚持使用本机for 循环。 - 无中断、继续或返回支持。
continue 实际上是由"意外"支持的,为了在angular.forEach 中继续,您只需将一个return; 语句放在类似angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); 的函数中,这将导致它继续超出该迭代的函数。这也是由于本地forEach 也不支持中断或继续。
我相信还有很多其他的优点和缺点,请随意添加您认为合适的。我觉得,底线是,如果你需要效率,就坚持使用原生的
foreach实现(请参见jfiddle中的):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 } ); |
如果您不介意清空数组:
1 2 3 4 5 6 7 | var x; while(x = y.pop()){ alert(x); //do something } |
jquery中有三个
1 2 3 4 5 | 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 |
现在一个简单的解决方案是使用underline.js库。它提供了许多有用的工具,如
其工作原理的代码笔示例是:
1 2 3 4 5 | var arr = ["elemA","elemB","elemC"]; _.each(arr, function(elem, index, ar) { ... }); |
也见
- 本地
Array.prototype.forEach() 文件。 - 在for-each…in(MDN)中,有人解释说,
for each (variable in object) 不推荐作为ECMA-357(EAX)标准的一部分。 - for…of(mdn)描述了下一种使用
for (variable of object) 作为和谐(ecmascript 6)建议的一部分的迭代方法。
可能
1 2 3 4 | var array = new Array(); array[1] ="Hello"; array[7] ="World"; array[11] ="!"; |
方法将从
1 2 3 4 5 | for(var i in array){ var el = array[i]; //If you want 'i' to be INT just put parseInt(i) //Do something with el } |
如果你希望它是一个函数,你可以这样做:
1 2 3 4 5 | function foreach(array, call){ for(var i in array){ call(array[i]); } } |
如果你想打破,再多点逻辑:
1 2 3 4 5 6 7 | function foreach(array, call){ for(var i in array){ if(call(array[i]) == false){ break; } } } |
例子:
1 2 3 4 5 6 7 | foreach(array, function(el){ if(el !="!"){ console.log(el); } else { console.log(el+"!!"); } }); |
它返回:
1 2 3 | //Hello //World //!!! |
作为的es6:
1 2 3 4 | list = [0, 1, 2, 3] for (let obj of list) { console.log(obj) } |
在与相关的oddities
的braces(
这是非稀疏列表的迭代器,索引从0开始,这是处理document.getElementsByTagname或document.querySelectorAll时的典型场景)
1 2 3 4 5 6 7 8 9 10 11 12 | 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
1 2 3 | var arr = []; [1, 2, 3].each( function(a){ a.push( this * this}, arr); arr = [1, 4, 9] |
例2
1 | each.call(document.getElementsByTagName('p'),"this.className = data;",'blue'); |
每个p标签得到
例3
1 2 3 4 | each.call(document.getElementsByTagName('p'), "if( i % 2 == 0) this.className = data;", 'red' ); |
每隔一个p标签得到
例4
1 2 3 4 5 6 | each.call(document.querySelectorAll('p.blue'), function(newClass, i) { if( i < 20 ) this.className = newClass; }, 'green' ); |
最后,前20个蓝色的P标签变为绿色。
当使用字符串作为函数时请注意:该函数是在上下文之外创建的,应该仅在确定变量作用域的情况下使用。否则,最好传递范围更直观的函数。
原生javascript中没有任何
1 2 3 | for (var instance in objects) { ... } |
但是,请注意,可能有理由使用更简单的
1 2 3 4 5 | var instance; for (var i=0; i < objects.length; i++) { var instance = objects[i]; ... } |
有几大环是一个安全的方式通过在JavaScript作为阵列,如下:
这是最为常见的一个。完整的代码为looping布拉克
1 2 3 4 5 6 | var languages = ["JAVA","JavaScript","C#","Python"]; var i, len, text; for (i = 0, len = languages.length, text =""; i < len; i++) { text += languages[i] +""; } document.getElementById("example").innerHTML = text; |
1 2 | <p id="example"> </p> |
而一个环,而条件是通过。它似乎是的fastest环
1 2 3 4 5 6 7 | var text =""; var i = 0; while (i < 10) { text += i +") something"; i++; } document.getElementById("example").innerHTML = text; |
1 2 | <p id="example"> </p> |
而我也因为/环通过一个块的代码,而威尔颤抖的条件是真的,至少一次
1 2 3 4 5 6 7 8 | var text ="" var i = 0; do { text += i +") something"; i++; } while (i < 10); document.getElementById("example").innerHTML = text; |
1 2 | <p id="example"> </p> |
功能loops -
1 2 3 | // 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}); |
1 2 | <p id="example"> </p> |
更多的信息和关于在arrays功能编程的例子,看看在博客发布在JavaScript编程功能:地图,滤波和减少。
ecmascript5(在JavaScript的版本与arrays)工作。
每一个项目iterates foreach -通过在阵列和做你需要与每个项目。
1 2 3 4 5 6 7 8 | ['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 |
在的情况下,更多的兴趣在使用的一些inbuilt操作在阵列特征。
这creates地图的一个新的研究结果与callback阵列的功能。这种方法是很好的大,是当你需要使用的阵列的元素的格式。
1 2 3 4 5 6 | // Let's upper case the items in the array ['bob', 'joe', 'jen'].map(function(elem) { return elem.toUpperCase(); }); // Output: ['BOB', 'JOE', 'JEN'] |
减少-作为它的名字说reduces阵列由一个单一的价值大的给定的功能通过电话在currenct元和结果公布的前一执行。
1 2 3 4 5 6 7 | [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 |
每一个returns真或假-如果在所有的元素,通过在callback阵列测试功能。
1 2 3 4 5 6 7 | // 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。
1 2 3 4 5 6 | // Finding the even numbers [1,2,3,4,5,6].filter(function(elem){ return (elem % 2 == 0) }); // Output: [2,4,6] |
希望这将是有用的。
没有内在的能力来破坏
1 2 3 | [1,2,3].some(function(number) { return number === 1; }); |
这是因为当按数组顺序执行的任何回调返回true时,
我还想将它添加为一个反向循环的组合,并为希望使用此语法的人提供上面的答案。
1 2 3 4 | var foo = [object,object,object]; for (var i = foo.length, item; item = foo[--i];) { console.log(item); } |
赞成的意见:
这样做的好处是:在第一行中已经有了这样的引用,以后就不需要用另一行声明了。在对象数组中循环时很方便。
欺骗:
当引用为假-假(未定义等)时,这将中断。不过,它可以作为一种优势。然而,它会使阅读变得有点困难。而且,根据浏览器的不同,它可以"不"优化,以比原来的更快地工作。
jQuery方式使用
1 2 3 4 5 6 7 8 9 | 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]; |
使用带有ES6破坏和扩展运算符的循环
破坏和使用spread操作符已经被证明对ES6的新用户非常有用,因为它更具人类可读性/审美性,尽管一些JavaScript老手可能认为它杂乱无章,但年轻人或其他人可能会发现它很有用。
The following examples will use
for...of statement and.forEach method.Examples 6, 7 and 8 can be used with any functional loops like
.map ,.filter ,.reduce ,.sort ,.every ,.some , for more information about these methods check out the Array Object.
例1:normal
1 2 3 4 5 | let arrSimple = ['a', 'b', 'c']; for (let letter of arrSimple) { console.log(letter); } |
示例2:将单词拆分为字符
1 2 3 4 5 6 7 8 | 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); } |
例3:与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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); } |
示例4:get object properties inline
1 2 3 4 5 6 7 8 9 10 11 12 13 | let arrWithObjects = [{ name: 'Jon', age: 32 }, { name: 'Elise', age: 33 } ]; for (let { name, age: aliasForAge } of arrWithObjects) { console.log(name, aliasForAge); } |
示例5:获取所需的深度对象属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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); } |
例6:例3是否与
1 2 3 4 5 6 7 8 9 10 11 12 | 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); }); |
例7:例4是否与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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) }); |
例8:例5是否与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | let arrWithObjectsWithArr = [{ name: 'Jon', age: 32, tags: ['driver', 'chef', 'jogger'] }, { name: 'Elise', age: 33, tags: ['best chef', 'singer', 'dancer'] } ]; arrWithObjectsWithArr.forEach(({ name, tags: [firstItemFromTags, ...restOfTags] }) => { console.log(name, firstItemFromTags, restOfTags); }); |
一个方法closest到你的想法会使用其中一个大
1 2 3 4 5 6 | myArray.forEach( (item) => { // do something console.log(item); } ); |
另一个可行的方式将大
1 2 3 4 5 6 7 8 | var myArray = [1, 2, 3]; myArray = myArray.map( (item) => { return item + 1; } ); console.log(myArray); // [2, 3, 4] |
通常的语法doesnt lambda IE工作在10或以下。
我通常使用的
1 2 3 4 5 6 7 8 9 10 11 12 | [].forEach.call(arrayName,function(value,index){ console.log("value of the looped element" + value); console.log("index of the looped element" + index); }); If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters $("#ul>li").each(function(**index,value**){ console.log("value of the looped element" + value); console.log("index of the looped element" + index); }); |
您可以这样调用foreach:
1 2 3 4 5 6 | let Array = [1,3,2]; theArray.forEach((element)=>{ // use the element of the array console.log(element) } |
元素将具有从0到数组长度的每个索引的值。
输出:
1 2 3 | 1 3 2 |
解释:
foreach在原型类中。您也可以将其称为array.prototype.foreach(…);
原型:https://hacker noon.com/prototype-in-javascript-5bba2990e04b
您还可以在这样的数组上进行更改:
1 2 3 | for(let i=0;i<theArray.length;i++){ console.log(i); //i will have the value of each index } |
如果要循环使用箭头函数的对象数组:
1 2 3 4 5 | [cc lang="javascript"]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'); }) |
< /代码>
总结:
在迭代数组时,我们通常希望实现以下目标之一:
我们要迭代数组并创建新数组:
我们希望遍历数组,而不创建新数组:
在JS中,有许多实现这两个目标的方法。然而,有些比其他更方便。在下面,您可以找到一些常用的方法(最方便的IMO)来在JavaScript中完成数组迭代。
创建新阵列:1 2 3 4 5 6 7 8 | let arr = [1, 2, 3, 4, 5]; let newArr = arr.map((element, index, array) => { return element * 2; }) console.log(arr); console.log(newArr); |
我们作为参数传递到
还要注意,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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); |
就像
1 2 3 4 5 | let arr = [1, 2, 3, 4, 5]; for(let element of arr) { console.log(element * 2); } |
在上面的例子中,
不要混淆
1 2 3 4 5 6 7 8 9 10 11 | 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); } |
如果要使代码保持功能性,请使用map:
1 | theArray.map(instance => do_something); |
这样,您将为将来的操作生成新的数组,并跳过任何不需要的副作用。
1 2 3 4 5 6 7 | // 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 }); |
如果你有一个大的,大量使用
提高效率iterators由肝脏产生不利影响的items不能说你在一个列表的一个在一个时间,如果他们是作为一个流。是什么使得它traverses iterator如何安全的特殊集合。其他loops需要load收集起来的整个前在大iterate超过它的顺序,而只需要知道的安全iterator当前打印位置的集合。
你当前的Access项目的iterator
regular阵列变换的方法使用大iterator
1 2 3 4 5 6 7 8 | 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()); |
你可以同时使用你的regular阵列变换大iterator
1 2 3 4 5 6 7 8 | 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()); |
你可以变换你的regular也大
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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} |
注:
- iterators是exhaustible性质。
- 对象是由不
iterable 安装默认。使用的情况下,而不是在for..in ,因为作品的价值与它的钥匙。
在这里你可以阅读更多关于
1 2 3 4 5 | var a = ["car","bus","truck"] a.forEach(function(item, index) { console.log("Index" + index); console.log("Element" + item); }) |
我来自Python,我发现这样更清楚。数组是数组,实例是数组的元素
1 2 3 4 | for(let instance of theArray) { console.log("The instance",instance); } |
或
1 2 3 4 | for( instance in theArray) { console.log("The instance",instance); } |
比较:
1 2 3 | theArray.forEach(function(instance) { console.log(instance); }); |
但在一天结束的时候,他们都在做同样的事情
您可以使用for each()API(由javascript提供),它接受函数作为回调,并为数组中的每个元素运行一次。
https://fullstackgeek.blogspot.com/2019/01/arrays-in-javascript-part-2.html
如果你想使用
1 2 3 | theArray.forEach ( element => { console.log(element); }); |
如果你想使用
1 2 3 4 | for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); } |