在Java中,您可以使用 for
循环遍历数组中的对象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
// Do something
}
你能用JavaScript做同样的事吗?
在Java中,您可以使用 for
循环遍历数组中的对象,如下所示:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
// Do something
}
你能用JavaScript做同样的事吗?
使用顺序 for
循环:
var myStringArray = ["Hello","World"];
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
alert(myStringArray[i]);
//Do something
}
@zipcodeman建议使用 for...in
声明,但用于迭代数组 for-in
应该避免,该声明是为了 枚举 对象属性。
它不应该用于类似数组的对象,因为:
第二点是,它可以给你很多问题,例如,如果你延长了 Array.prototype
要包含一个方法的对象,该属性也将被枚举。
例如:
Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];
for (var i in array) {
alert(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)) {
// or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
alert("prop: " + prop + " value: " + obj[prop])
}
}
在上面的例子中 hasOwnProperty
方法允许您仅枚举 自己的财产就是这样,只有对象物理上具有的属性,没有继承属性。
我建议你阅读以下文章:
是的,但仅当您的实施包括 for
...of
功能介绍 ECMAScript 2015 (“和谐”版本)。
它的工作原理如下:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
或者更好,因为ECMAScript 2015还提供了块范围的变量 let
和 const
:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
然而,许多JavaScript开发人员仍然在一个尚未出现的环境中工作 - 特别是如果编写代码以在Web浏览器中运行,那么网站开发人员通常无法确定他们的客户将使用哪种浏览器/版本。
如果你可以假设JavaScript解释器符合 以前 ECMAScript规范的版本(例如,排除9之前的Internet Explorer版本),然后你可以使用 forEach
迭代器方法而不是循环。在这种情况下,您传递一个要在数组中的每个项目上调用的函数:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
但是,即使这样做太多了,你也想要一些有用的东西 所有 JavaScript的版本,然后你必须使用显式计数循环。最安全的版本,正确处理稀疏数组,如下所示:
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) {
该 for
...in
别人提到的语法是循环对象的属性;因为JavaScript中的数组只是一个具有数字属性名称的对象(并且是自动更新的 length
你可以理论上用它循环一个数组。但问题是它并不局限于数值属性值(请记住,即使方法实际上只是其值为闭包的属性),也不会按数字顺序迭代它们。因此, for
...in
语法应该 不 用于循环遍历数组。
您可以使用 map
,这是一种功能性编程技术,也可用于其他语言 蟒蛇 和 哈斯克尔。
[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
。
在JavaScript中,不建议使用for-in循环遍历数组,但最好使用for循环,例如:
for(var i=0, len=myArray.length; i < len; i++){}
它也被优化(“缓存”数组长度)。如果你想了解更多, 阅读我关于这个主题的帖子。
(直接回答你的问题:现在你可以!)
大多数其他答案是正确的,但他们没有提及(截至本文撰写时) ECMA脚本 6 2015年 正在带来一种新的迭代机制 for..of
循环。
这种新语法是在javascript中迭代数组的最优雅方式(只要你不需要迭代索引),但它还没有被浏览器广泛支持。
它目前适用于Firefox 13 +,Chrome 37+,它本身不能与其他浏览器一起使用(请参阅下面的浏览器兼容性)。幸运的是我们有JS编译器(例如 巴别塔)允许我们今天使用下一代功能。
它也适用于Node(我在版本0.12.0上测试过它)。
迭代一个数组
// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) {
console.log(letter);
}
迭代一个对象数组
var band = [
{firstName : 'John', lastName: 'Lennon'},
{firstName : 'Paul', lastName: 'McCartney'}
];
for(var 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 (let n of fibonacci()) {
console.log(n);
// truncate the sequence at 1000
if (n >= 1000) {
break;
}
}
兼容性表: http://kangax.github.io/es5-compat-table/es6/#For..of循环
规格: http://wiki.ecmascript.org/doku.php?id=harmony:iterators
Opera,Safari,Firefox和Chrome现在都共享一组增强的Array方法,用于优化许多常见循环。
您可能不需要所有这些,但它们可能非常有用,或者如果每个浏览器都支持它们。
Mozilla Labs发布了他们和的算法 WebKit的 两者都使用,以便您可以自己添加它们。
过滤 返回满足某些条件或测试的项数组。
一切 如果每个数组成员都通过测试,则返回true。
一些 如果有任何通过测试,则返回true。
的forEach 在每个数组成员上运行一个函数,不返回任何内容。
地图 就像forEach一样,但它返回每个元素的操作结果数组。
这些方法都为它们的第一个参数提供了一个函数,并且有一个可选的第二个参数,该参数是一个对象,当它们循环遍历函数时,它们要在数组成员上施加范围。
忽略它直到你需要它。
指数 和 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;
})();
使用while循环...
var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
console.log(item);
}
日志:'one','two','three'
而对于相反的顺序,一个更有效的循环
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]);
}
日志:'one','two','three'
参考: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/
自从我上大学以来,我用Java,JavaScript,Pascal编程, ABAP,PHP,Progress 4GL,C / C ++以及其他一些我现在想不到的语言。
虽然它们都有自己的语言特性,但每种语言都有许多相同的基本概念。这些概念包括程序/功能, IF
-statements, FOR
-loops,和 WHILE
-loops。
for
-循环传统的 for
循环有三个组成部分:
这三个组件通过a分开 ;
符号。这三个组件中的每一个的内容都是可选的,这意味着以下内容是最小的 for
循环可能:
for (;;) {
// Do stuff
}
当然,你需要包括一个 if(condition === true) { break; }
或者 if(condition === true) { return; }
在里面的某个地方 for
-loop让它停止运行。
但是,通常,初始化用于声明索引,条件用于将该索引与最小值或最大值进行比较,并使用事后补充来增加索引:
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循环都可以重写为a for
循环。例如, while
上面的循环行为与此完全相同 for
-循环:
for(var key = 0; value = myArray[key++];){
console.log(value);
}
For...in
和 for...of
在JavaScript中,您也可以这样做:
for (i in myArray) {
console.log(myArray[i]);
}
但是,这应该谨慎使用,因为它的行为与传统行为不同 for
在所有情况下循环,并且存在需要考虑的潜在副作用。看到 为什么在数组迭代中使用“for ... in”是一个坏主意? 更多细节。
作为替代 for...in
,现在也有 for...of
。以下示例显示了a之间的区别 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
(边缘12+ 并且那 for...in
至少需要Internet Explorer 10。
Array.prototype.forEach()
替代 for
-loops是 Array.prototype.forEach()
,它使用以下语法:
myArray.forEach(function(value, key, myArray) {
console.log(value);
});
Array.prototype.forEach()
所有现代浏览器以及Internet Explorer 9及更高版本都支持。
最后,许多实用程序库也有自己的 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);
});
如果你想要一种简洁的方法来编写快速循环 和 你可以反向迭代:
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)
)虽然要输入更少的字符。
甚至有些时候你应该反向迭代,例如迭代时 实时NodeList 您计划在迭代期间从DOM中删除项目的位置。
有一种方法可以在循环中具有非常小的隐式范围并且消除额外的变量。
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.
}
或者,如果你真的想要获得身份证并拥有非常经典的身份 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
以及其他一些方法 数组原型。