在 Java 中,您可以使用 for
循环遍历数组中的对象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray) {
// Do something
}
我可以在 JavaScript 中做同样的事情吗?
for-in
循环枚举对象属性,没有特定顺序,它还枚举继承的属性...对于数组迭代,始终建议使用顺序循环...
in
和 of
来做不同的事情。然后你还有 forEach
和丑陋和恼人的基于索引的循环。其他所有现代语言都使循环遍历集合变得简单直接,没有任何意外或混乱。 JS 也可以,但它没有。
三个主要选项:
for (var i = 0; i < xs.length; i++) { console.log(xs[i]); xs.forEach((x, i) => console.log(x)); for (const x of xs) { console.log(x); }
详细示例如下。
1.顺序for循环:
var myStringArray = ["Hello","World"]; var arrayLength = myStringArray.length; for (var i = 0; i < arrayLength; i++) { console.log(myStringArray[i]); //做一点事 }
优点
适用于各种环境
您可以使用 break 和 continue 流控制语句
缺点
太冗长
至关重要的
容易出现一个错误(有时也称为栅栏柱错误)
2. Array.prototype.forEach:
ES5 规范引入了许多有益的数组方法。其中一个 Array.prototype.forEach
为我们提供了一种迭代数组的简洁方法:
const array = ["one", "two", "three"] array.forEach(function (item, index) { console.log(item, index); });
在编写 ES5 规范发布(2009 年 12 月)时已经将近十年了,它已被桌面、服务器和移动环境中的几乎所有现代引擎实现,因此使用它们是安全的。
并且使用 ES6 箭头函数语法,它更加简洁:
array.forEach(item => console.log(item));
除非您计划支持古老的平台(例如,Internet Explorer 11),否则箭头函数也被广泛实现;你也可以安全前往。
优点
非常简短和简洁。
声明式
缺点
不能使用中断/继续
通常,您可以通过在迭代数组元素之前过滤数组元素来替换命令式循环中对 break
的需要,例如:
array.filter(item => item.condition < 10)
.forEach(item => console.log(item))
请记住,如果您正在迭代一个数组以从中构建另一个数组,您应该使用 map
。我已经多次看到这种反模式。
反模式:
const numbers = [1,2,3,4,5], doubled = [];
numbers.forEach((n, i) => { doubled[i] = n * 2 });
地图的正确用例:
常量数字 = [1,2,3,4,5]; const doubled = numbers.map(n => n * 2);控制台.log(加倍);
此外,如果您尝试将数组归约为一个值,例如,您想对一个数字数组求和,则应使用 reduce 方法。
反模式:
const numbers = [1,2,3,4,5];
const sum = 0;
numbers.forEach(num => { sum += num });
正确使用reduce:
常量数字 = [1,2,3,4,5]; const sum = numbers.reduce((total, n) => total + n, 0);控制台.log(总和);
3. ES6 for-of 语句:
ES6 标准引入了可迭代对象的概念,并定义了一个用于遍历数据的新结构,即 for...of
语句。
此语句适用于任何类型的可迭代对象以及生成器(任何具有 \[Symbol.iterator\]
属性的对象)。
数组对象是 ES6 中定义的内置可迭代对象,因此您可以对它们使用以下语句:
let colors = ['red', 'green', 'blue'];
for (const color of colors){
console.log(color);
}
优点
它可以迭代各种各样的对象。
可以使用正常的流控制语句(break/continue)。
对于迭代串行异步值很有用。
缺点
如果您的目标是较旧的浏览器,转译后的输出可能会让您大吃一惊。
不要用于...in
@zipcodeman 建议使用 for...in
语句,但对于迭代数组 for-in
应避免使用,该语句旨在枚举对象属性。
它不应该用于类似数组的对象,因为:
不保证迭代的顺序;数组索引可能不会按数字顺序访问。
还列举了继承的属性。
第二点是它会给您带来很多问题,例如,如果您扩展 Array.prototype
对象以在其中包含一个方法,那么该属性也会被枚举。
例如:
Array.prototype.foo = "foo!"; var 数组 = ['a', 'b', 'c']; for (var i in array) { console.log(array[i]); }
上面的代码将控制台记录“a”、“b”、“c”和“foo!”。
如果您使用一些严重依赖原生原型扩充的库(例如 MooTools),这可能会成为一个特别的问题。
正如我之前所说,for-in
语句用于枚举 对象属性,例如:
var obj = { "a": 1, "b": 2, "c": 3 }; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { // 或者 if (Object.prototype.hasOwnProperty.call(obj,prop)) 为了安全... console.log("prop: " +道具 + " 值: " + obj[prop]) } }
在上面的示例中,hasOwnProperty
方法只允许您枚举自己的属性。就是这样,只有对象物理具有的属性,没有继承的属性。
我建议您阅读以下文章:
枚举 VS 迭代
是的,假设您的实现包括 ECMAScript 2015(“Harmony”版本)中引入的 for
...of
功能……这在当今是一个相当安全的假设。
它是这样工作的:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
或者更好的是,因为 ECMAScript 2015 还提供了块范围的变量:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
(变量 s
在每次迭代中都不同,但仍然可以在循环体中声明为 const
,只要它没有在那里被修改。)
关于稀疏数组的注意事项:JavaScript 中的数组实际上存储的项目可能没有其 length
报告的那么多;该报告的数字仅比存储值的最高索引大一。如果数组包含的元素少于其长度所指示的元素,则称其为稀疏。例如,拥有一个仅在索引 3、12 和 247 处包含项目的数组是完全合法的;这样一个数组的 length
报告为 248,尽管它实际上只存储了 3 个值。如果您尝试访问任何其他索引处的项目,则该数组将在那里显示 undefined
值。因此,当您想“遍历”一个数组时,您需要回答一个问题:您是要遍历其长度指示的整个范围并处理 undefined
以查找任何缺失的元素,还是只想处理实际存在的元素?这两种方法都有很多应用。这仅取决于您使用数组的目的。
如果您使用 for
..of
对数组进行迭代,则循环体将执行 length
次,并且对于数组中实际不存在的任何项目,循环控制变量都设置为 undefined
。根据您“使用”代码的详细信息,该行为可能是您想要的,但如果不是,您应该使用不同的方法。
当然,一些开发人员别无选择,只能使用不同的方法,因为无论出于何种原因,他们的目标都是不支持 for
...of
的 JavaScript 版本。
只要您的 JavaScript 实现符合以前版本的 ECMAScript 规范(例如,排除了 Internet Explorer 9 之前的版本),那么您就可以改用 Array#forEach
迭代器方法的一个循环。在这种情况下,您传递一个要在数组中的每个项目上调用的函数:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
与 for
...of
不同,.forEach
只为数组中实际存在的元素调用函数。如果传递我们假设的具有三个元素且长度为 248 的数组,它只会调用该函数 3 次,而不是 248 次。它还区分了缺失元素和实际设置为 undefined
的元素;对于后者,它仍然会调用函数,传递 undefined
作为参数。如果这是您想要处理稀疏数组的方式,即使您的解释器支持 for
...of
,.forEach
也可能是可行的方法。
最后一个选项是 an explicit counting loop,它适用于 所有 版本的 JavaScript。您只需从 0 数到比长度小一,然后使用计数器作为索引。基本循环如下所示:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
这种方法的一个优点是您可以选择如何处理稀疏数组;上面的代码将循环体运行完整的 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 ...
}
}
将长度值分配给局部变量(与在循环条件中包含完整的 myStringArray.length
表达式相反)可以显着提高性能,因为它每次都会跳过属性查找;在我的机器上使用 Rhino,加速是 43%。
您可能会在循环初始化子句中看到长度缓存,如下所示:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
如果需要,显式计数循环还意味着您可以访问每个值的索引。索引也作为额外参数传递给您传递给 forEach
的函数,因此您也可以通过这种方式访问它:
myStringArray.forEach( function(s, i) {
// ... do something with s and i ...
});
for
...of
不会为您提供与每个对象关联的索引,但只要您正在迭代的对象实际上是 Array
(for
..of
适用于其他对象可能没有此方法的可迭代类型),您可以使用 Array#entries 方法将其更改为 [index, item] 对的数组,然后对其进行迭代:
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
其他人提到的 for
...in
语法是用于循环对象的属性;由于 JavaScript 中的 Array 只是一个具有数字属性名称的对象(以及一个自动更新的 length
属性),因此理论上您可以使用它循环遍历 Array。但问题是它并不局限于数字属性值(请记住,即使方法实际上只是其值为闭包的属性),也不能保证按数字顺序迭代那些。因此,for
...in
语法应该不用于遍历数组。
您可以使用 map
,这是一种函数式编程技术,也可用于其他语言,如 Python 和 Haskell。
[1,2,3,4].map( function(item) {
alert(item);
})
一般语法是:
array.map(func)
通常 func
将采用一个参数,它是数组的一项。但在 JavaScript 的情况下,它可以采用第二个参数,即项目的索引,以及第三个参数,即数组本身。
array.map
的返回值是另一个数组,因此您可以像这样使用它:
var x = [1,2,3,4].map( function(item) {return item * 10;});
现在 x 是 [10,20,30,40]
。
您不必内联编写函数。它可以是一个单独的功能。
var item_processor = function(item) {
// Do something complicated to an item
}
new_list = my_list.map(item_processor);
这将相当于:
for (item in my_list) {item_processor(item);}
除非您没有得到 new_list
。
Array.forEach
可能会更好地实现该特定示例。 map
用于生成新数组。
Array.prototype.map
方法是 ECMAScript 第 5 版标准的一部分,尚未在所有实现上都可用(例如 IE 缺少它),也用于 iterating 数组我认为 {1 } 方法更语义正确...也请不要建议 for-in 语句,有关更多详细信息,请参阅我的答案 :)
for (const s of myStringArray) {
(直接回答你的问题:现在你可以了!)
大多数其他答案都是正确的,但他们没有提到(在撰写本文时)ECMAScript 6 2015 带来了一种新的迭代机制,即 for..of
循环。
这种新语法是在 JavaScript 中迭代数组的最优雅的方式(只要您不需要迭代索引)。
它目前适用于 Firefox 13+、Chrome 37+,并且本身不适用于其他浏览器(请参阅下面的浏览器兼容性)。幸运的是,我们拥有 JavaScript 编译器(例如 Babel),使我们能够在今天使用下一代功能。
它也适用于 Node.js(我在 0.12.0 版本上对其进行了测试)。
迭代数组
// You could also use "let" or "const" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
console.log(letter);
}
迭代对象数组
const band = [
{firstName : 'John', lastName: 'Lennon'},
{firstName : 'Paul', lastName: 'McCartney'}
];
for(const member of band){
console.log(member.firstName + ' ' + member.lastName);
}
迭代生成器:
(摘自 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 (const n of fibonacci()) {
console.log(n);
// Truncate the sequence at 1000
if (n >= 1000) {
break;
}
}
兼容性表: http://kangax.github.io/compat-table/es6/#test-for..of_loops
规格: http://wiki.ecmascript.org/doku.php?id=harmony:iterators
}
在 JavaScript 中,不建议使用 for-in 循环遍历 Array,但最好使用 for
循环,例如:
for(var i=0, len=myArray.length; i < len; i++){}
它也经过优化(“缓存”数组长度)。如果您想了解更多信息,read my post on the subject。
Opera、Safari、Firefox 和 Chrome 现在都共享一组增强的 Array 方法,用于优化许多常见的循环。
您可能不需要所有这些,但它们可能非常有用,或者如果每个浏览器都支持它们的话。
Mozilla 实验室发布了他们和 WebKit 都使用的算法,以便您自己添加它们。
过滤器返回满足某些条件或测试的项目数组。
如果每个数组成员都通过了测试,则 each 返回 true。
如果有任何通过测试,则 some 返回 true。
forEach 在每个数组成员上运行一个函数并且不返回任何内容。
map 类似于 forEach,但它返回一个包含每个元素的操作结果的数组。
这些方法都采用一个函数作为它们的第一个参数,并有一个可选的第二个参数,这是一个对象,您希望在数组成员循环通过函数时将其范围强加于它们。
忽略它,直到你需要它。
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;
})();
6种不同的方法来遍历数组
您可以通过许多不同的方法循环遍历数组。我从上到下对我最喜欢的 6 种方法进行了排序。
1.使用for循环
当它是简单地遍历一个数组时,for
循环是我的首选。
让数组 = [1, 2, 3, 4, 5]; for (let i = 0; i < array.length; i++) { console.log(array[i]); }
2.使用forEach循环
forEach
循环是一种遍历数组的现代方式。此外,它提供了更多的灵活性和对数组和元素的控制。
让数组 = [1, 2, 3, 4, 5]; array.forEach((element) => { console.log(element); });
3. 使用 for...of
for...of
循环使您可以直接访问数组元素。
让数组 = [1, 2, 3, 4, 5]; for (let element of array) { console.log(element); }
4. 使用 for...in 循环
for...in
为您提供了一个可以访问数组元素的键。
让数组 = [1, 2, 3, 4, 5]; for(让数组中的索引){ console.log(array[index]); }
5.使用while循环
while 循环也可用于遍历数组。
让数组 = [1, 2, 3, 4, 5];让长度 = 数组长度;而(长度> 0){ console.log(数组[array.length - 长度]);长度 - ; }
6. 使用 do...while 循环
同样,我使用 do...while
循环
让数组 = [1, 2, 3, 4, 5];让长度 = 数组长度;做 { console.log(array[array.length - length]);长度 - ; } 而(长度> 0)
介绍
自从我上大学以来,我已经使用 Java、JavaScript、Pascal、ABAP、PHP、Progress 4GL、C/C++ 以及一些我现在想不出的其他语言进行编程。
虽然它们都有自己的语言特性,但这些语言中的每一种都有许多相同的基本概念。此类概念包括过程/函数、IF
-语句、FOR
-循环和 WHILE
-循环。
传统的for循环
传统的 for
循环包含三个组件:
初始化:在第一次执行look块之前执行条件:每次执行循环块之前检查一个条件,如果为false则退出循环事后思考:每次执行循环块之后执行
这三个组件由 ;
符号相互分隔。这三个组件中的每一个的内容都是可选的,这意味着以下是可能的最小 for
循环:
for (;;) {
// Do stuff
}
当然,您需要在该 for
循环内的某处包含一个 if(condition === true) { break; }
或一个 if(condition === true) { return; }
以使其停止运行。
但是,通常初始化用于声明索引,条件用于将该索引与最小值或最大值进行比较,事后考虑用于增加索引:
for (var i = 0, length = 10; i < length; i++) {
console.log(i);
}
使用传统的 for 循环遍历数组
遍历数组的传统方法是:
for (var i = 0, length = myArray.length; i < length; i++) {
console.log(myArray[i]);
}
或者,如果您更喜欢向后循环,请执行以下操作:
for (var i = myArray.length - 1; i > -1; i--) {
console.log(myArray[i]);
}
但是,可能有许多变化,例如这个:
for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
console.log(value);
}
……或者这个……
var i = 0, length = myArray.length;
for (; i < length;) {
console.log(myArray[i]);
i++;
}
...或者这个:
var key = 0, value;
for (; value = myArray[key++];){
console.log(value);
}
哪个效果最好在很大程度上取决于个人品味和您正在实施的特定用例。
请注意,所有浏览器都支持这些变体中的每一个,包括非常非常旧的浏览器!
一个while循环
for
循环的一种替代方法是 while
循环。要遍历数组,您可以这样做:
var key = 0;
while(value = myArray[key++]){
console.log(value);
}
与传统的 for
循环一样,即使是最古老的浏览器也支持 while
循环。
另外,请注意,每个 while 循环都可以重写为 for
循环。例如,上述 while
循环的行为方式与此 for
循环完全相同:
for(var key = 0; value = myArray[key++];){
console.log(value);
}
为...在和为...的
在 JavaScript 中,您也可以这样做:
for (i in myArray) {
console.log(myArray[i]);
}
然而,这应该小心使用,因为在所有情况下它的行为都与传统的 for
循环不同,并且需要考虑潜在的副作用。有关详细信息,请参阅 Why is using "for...in" for array iteration a bad idea?。
作为 for...in
的替代品,现在还有 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
}
此外,您需要考虑没有任何版本的 Internet Explorer 支持 for...of
(Edge 12+ 支持)并且 for...in
至少需要 Internet Explorer 10。
Array.prototype.forEach()
for
循环的替代方法是 Array.prototype.forEach()
,它使用以下语法:
myArray.forEach(function(value, key, myArray) {
console.log(value);
});
所有现代浏览器以及 Internet Explorer 9 及更高版本都支持 Array.prototype.forEach()
。
图书馆
最后,许多实用程序库也有自己的 foreach
变体。 AFAIK,最受欢迎的三个是:
$.each(myArray, function(key, value) {
console.log(value);
});
_.each(myArray, function(value, key, myArray) {
console.log(value);
});
_.forEach(myArray, function(value, key) {
console.log(value);
});
使用while循环...
var i = 0, item, items = ['one', 'two', 'three'];
while(item = items[i++]){
console.log(item);
}
它记录:“一”、“二”和“三”
而对于相反的顺序,一个更有效的循环:
var items = ['one', 'two', 'three'], i = items.length;
while(i--){
console.log(items[i]);
}
它记录:“三”、“二”和“一”
或者经典的 for
循环:
var items = ['one', 'two', 'three']
for(var i=0, l = items.length; i < l; i++){
console.log(items[i]);
}
它记录:'一','二','三'
参考:Google Closure: How not to write JavaScript
如果您想要一种简洁的方式来编写快速循环,并且可以反向迭代:
for (var i=myArray.length;i--;){
var item=myArray[i];
}
这样做的好处是缓存长度(类似于 for (var i=0, len=myArray.length; i<len; ++i)
而不同于 for (var i=0; i<myArray.length; ++i)
),同时输入的字符更少。
有时您甚至应该进行反向迭代,例如在您计划在迭代期间从 DOM 中删除项目的 live NodeList 上进行迭代时。
在 JavaScript 中以函数式编程方式循环数组的一些用例:
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
});
注意: Array.prototype.forEach() 严格来说不是函数方式,因为它作为输入参数的函数不应该返回值,因此不能被视为纯函数。
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.转换为新数组
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]
注意: map() 方法创建一个新数组,其结果是在调用数组中的每个元素上调用提供的函数。
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.在原有的基础上新建一个数组,但不修改
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.统计每个类别的数量
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. 根据特定标准检索数组的子集
const myArray = [{x:100}, {x:200}, {x:300}];
const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}]
注意: filter() 方法创建一个新数组,其中包含通过提供的函数实现的测试的所有元素。
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);
https://i.stack.imgur.com/scSsS.png
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);
https://i.stack.imgur.com/ODT69.png
Array.prototype.find() 方法返回数组中满足提供的测试函数的第一个元素的值。
参考
Array.prototype.some()
Array.prototype.forEach()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.sort()
传播语法
Array.prototype.find()
是的,你可以在 JavaScript 中使用循环来做同样的事情,但不限于此。有很多方法可以在 JavaScript 中对数组进行循环。假设您在下面有这个数组,并且您想对其进行循环:
var arr = [1, 2, 3, 4, 5];
这些是解决方案:
1)for循环
for
循环是 JavaScript 中遍历数组的常用方法,但它不被视为大型数组的最快解决方案:
for (var i=0, l=arr.length; i<l; i++) {
console.log(arr[i]);
}
2)while循环
while 循环被认为是循环长数组的最快方式,但在 JavaScript 代码中通常较少使用:
let i=0;
while (arr.length>i) {
console.log(arr[i]);
i++;
}
3) Do while
do while
与 while
执行相同的操作,但语法差异如下:
let i=0;
do {
console.log(arr[i]);
i++;
}
while (arr.length>i);
这些是执行 JavaScript 循环的主要方法,但还有其他几种方法可以做到这一点。
我们还使用 for in
循环来循环 JavaScript 中的对象。
另请查看 JavaScript 中数组上的 map()
、filter()
、reduce()
等函数。他们可能比使用 while
和 for
更快更好地完成任务。
如果您想了解更多关于 JavaScript 中数组上的异步函数的信息,这是一篇很好的文章。
这些天来,函数式编程在开发界引起了轰动。并且有充分的理由:函数式技术可以帮助您编写更易于一目了然、重构和测试的声明性代码。函数式编程的基石之一是它对列表和列表操作的特殊使用。而这些东西正是它们听起来的样子:一系列的东西,以及你对它们所做的事情。但是功能性思维方式对待它们的方式与您预期的有所不同。本文将仔细研究我喜欢称之为“三巨头”的列表操作:map、filter 和 reduce。围绕这三个函数展开思考是朝着编写干净的函数式代码迈出的重要一步,并为函数式和反应式编程的强大技术打开了大门。这也意味着您永远不必再次编写 for 循环。
阅读更多>> here:
有一种方法可以做到这一点,您的循环中的隐式范围非常小,并消除了额外的变量。
var i = 0,
item;
// Note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){
item; // This is the string at the index.
}
或者,如果您真的想获得 id 并拥有一个非常经典的 for
循环:
var i = 0,
len = myStringArray.length; // Cache the length
for ( ; i < len ; i++ ){
myStringArray[i]; // Don't use this if you plan on changing the length of the array
}
现代浏览器都支持迭代器方法 forEach
、map
、reduce
、filter
以及 Array prototype 上的许多其他方法。
在 JavaScript 中有多种循环遍历数组的方法。
通用循环:
var i;
for (i = 0; i < substr.length; ++i) {
// Do something with `substr[i]`
}
ES5 的 forEach:
substr.forEach(function(item) {
// Do something with `item`
});
jQuery.每个:
jQuery.each(substr, function(index, item) {
// Do something with `item` (or `this` is also `item` if you like)
});
查看 this 以获取详细信息,或者您也可以查看 MDN 以在 JavaScript & 中循环遍历数组。使用 jQuery 检查 jQuery for each。
数组循环:
for(var i = 0; i < things.length; i++){
var thing = things[i];
console.log(thing);
}
对象循环:
for(var prop in obj){
var propValue = obj[prop];
console.log(propValue);
}
我强烈推荐使用 Underscore.js 库。它为您提供了可用于迭代数组/集合的各种函数。
例如:
_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
如果有人对 Array 迭代可用的多种机制的性能方面感兴趣,我准备了以下 JSPerf 测试:
https://jsperf.com/fastest-array-iterator
https://i.stack.imgur.com/UOJ9F.jpg
结果:
传统的 for()
迭代器是迄今为止最快的方法,尤其是与 缓存的数组长度一起使用时。
let arr = [1,2,3,4,5];
for(let i=0, size=arr.length; i<size; i++){
// Do something
}
Array.prototype.forEach()
和 Array.prototype.map()
方法是最慢的近似值,这可能是 函数调用开销的结果。
i = i +1
而不是 i++
我还没有看到这种变化,我个人最喜欢它:
给定一个数组:
var someArray = ["some", "example", "array"];
您可以在不访问 length 属性的情况下遍历它:
for (var i=0, item; item=someArray[i]; i++) {
// item is "some", then "example", then "array"
// i is the index of item in the array
alert("someArray[" + i + "]: " + item);
}
请参阅此 JsFiddle 证明:http://jsfiddle.net/prvzk/
这仅适用于非稀疏的数组。这意味着数组中的每个索引实际上都有一个值。但是,我发现在实践中我几乎从不使用 JavaScript 中的稀疏数组……在这种情况下,将对象用作映射/哈希表通常要容易得多。如果你确实有一个稀疏数组,并且想要循环 0 .. length-1,你需要 for (var i=0; i
此外,正如 CMS 在下面的评论中提到的那样,您只能在不包含任何虚假值的数组上使用它。示例中的字符串数组有效,但如果您有空字符串,或者数字为 0 或 NaN 等,则循环将过早中断。同样在实践中,这对我来说几乎不是问题,但要牢记这一点,这使得在使用它之前要考虑一个循环......这可能会让某些人失去资格:)
我喜欢这个循环的地方是:
写的很短
无需访问(更不用说缓存)长度属性
要访问的项目在您选择的名称下的循环主体内自动定义。
非常自然地与 array.push 和 array.splice 结合使用数组,如列表/堆栈
这样做的原因是数组规范要求当您从索引中读取一个 >= 数组长度的项目时,它将返回未定义的。当您写入这样的位置时,它实际上会更新长度。
对我来说,这个结构最接近地模拟了我喜欢的 Java 5 语法:
for (String item : someArray) {
}
...还有一个额外的好处是还知道循环内的当前索引
0
、false
、NaN
、null
或 undefined
)后立即停止,甚至在 i
达到长度之前,例如:jsfiddle.net/prvzk/1
(item=someArray[i]) !== undefined
。
如果您使用的是 jQuery 库,请考虑使用 http://api.jquery.com/jQuery.each/
从文档中:
jQuery.each(collection, callback(indexInArray, valueOfElement)) 返回: 对象描述: 一个通用的迭代器函数,可以用来无缝地迭代对象和数组。具有长度属性的数组和类数组对象(例如函数的 arguments 对象)通过数字索引进行迭代,从 0 到 length-1。其他对象通过其命名属性进行迭代。 $.each() 函数与 $(selector).each() 不同,后者用于以独占方式遍历 jQuery 对象。 $.each() 函数可用于迭代任何集合,无论是映射(JavaScript 对象)还是数组。在数组的情况下,回调每次都会传递一个数组索引和一个对应的数组值。 (该值也可以通过 this 关键字访问,但 Javascript 将始终将 this 值包装为一个对象,即使它是一个简单的字符串或数字值。)该方法返回其第一个参数,即被迭代的对象。
数组迭代有4种方式:
// 1: for
for (let i = 0; i < arr.length; ++i) {
console.log(arr[i]);
}
// 2: forEach
arr.forEach((v, i) => console.log(v));
// 3: for in
for (let i in arr) {
console.log(arr[i]);
}
// 4: for of
for (const v of arr) {
console.log(v);
}
摘要:1 和 3 解决方案创建额外的变量,2 - 创建额外的函数上下文。最好的方法是第 4 种 - “for of”。
深奥的可变方式
让 a= ["Hello", "World"]; while(a.length) { console.log(a.shift() ); }
while(a.length) { console.log(a.shift()); }
的速度大约是 for(var i = 0; i < a.length; i++) { console.log(a[i]); }
版本的两倍。 ¯\_(ツ)_/¯
有一种方法可以仅迭代自己的对象属性,不包括原型的属性:
for (var i in array) if (array.hasOwnProperty(i)) {
// Do something with array[i]
}
但它仍然会遍历自定义属性。
在 JavaScript 中,任何自定义属性都可以分配给任何对象,包括数组。
如果要遍历稀疏数组,则应使用带有 es5shim
的 for (var i = 0; i < array.length; i++) if (i in array)
或 array.forEach
。
for (var i in array) if (++i)
怎么样?
最优雅快捷的方式
var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
value + 1
}
http://jsperf.com/native-loop-performance/8
已编辑(因为我错了)
比较循环遍历 100000 个项目的数组的方法,并每次对新值进行最小操作。
http://jsben.ch/#/BQhED
准备:
<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
Benchmark.prototype.setup = function() {
// Fake function with minimal action on the value
var tmp = 0;
var process = function(value) {
tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
};
// Declare the test Array
var arr = [];
for (var i = 0; i < 100000; i++)
arr[i] = i;
};
</script>
测试:
<a href="http://jsperf.com/native-loop-performance/16"
title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>
在 JavaScript 中有几种方法可以做到这一点。前两个示例是 JavaScript 示例。第三个使用了 JavaScript 库,即 jQuery 使用了 .each()
函数。
var myStringArray = [“你好”,“世界”]; for(var i in myStringArray) { alert(myStringArray[i]); }
var myStringArray = [“你好”,“世界”]; for (var i=0; i < myStringArray.length; i++) { alert(myStringArray[i]); }
var myStringArray = [“你好”,“世界”]; $.each(myStringArray, function(index, value){ alert(value); })
forEach
不等待承诺。确保您在使用承诺(或异步函数)时了解其含义作为forEach
回调。” (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)for-of
的缺点:无法获取当前索引for(let ojb of objs)
语句呢?