问题
I found that there is a difference between for loop and for-in loop in javascript.
When I define a new array:
var a=new Array();
Then I put some value into in but not contiguously for example:
a[0]=0;a[1]=1;a[4]=4;
When I use for(i=0;i<5;i++)
to get the value and use alert to show it, it's different from using for(i in a)
.
The previous one will show elements in index 2,3 which shows "undefined" while for-in will show only index 0,1,and 4. Can anybody tell me why?
回答1:
for (... in ...)
is typically used to iterate through the properties of objects (which are what javaScript uses for associative arrays), while the typical for
loop is used for sequential arrays.
In your example, you are really creating an associative array with the keys 0, 1, and 4. If you wanted a true javaScript array, you'd use a.push(0)
, a.push(1)
, etc... in order to add the values, sequentially, onto the end of the array.
With a sequential array, the syntax for (var i = 0; i < arr.length; i++)
makes i
count from 0 to 1 less than the length of the array. This will allow i
to be equal to each index in the array, one-by-one, allowing you to access each element in that array.
With associative arrays, however, the keys are non-sequential, so making a variable count 'from 0 to 1 less than the length of the array' won't produce the desired results. In your example it is close to working because your manually created keys just happen to be 0, 1, and 4, which are almost sequential.
If you want to have an array with non-sequential keys--'non-contiguous' as in 0, 1, 4, etc..--you should probably use objects, not arrays, e.g.
var obj = {};
obj[0] = 0;
obj[1] = 1;
obj[4] = 4;
And then using the for (... in ...)
loop would be the correct syntax.
回答2:
For loop iterates over them until the i reaches to 5 so i = 0,1,2,3,4,5 and iterates over all. But with for...in loop iterates over their properties only not 0 to 5 but 0,1,4 that you've defined.
From MDN:
Note: for..in should not be used to iterate over an Array where index order is important.
Array indexes are just enumerable properties with integer names and are otherwise identical to general Object properties. There is no guarantee that for...in will return the indexes in any particular order and it will return all enumerable properties, including those with non–integer names and those that are inherited.
Because the order of iteration is implementation dependent, iterating over an array may not visit elements in a consistent order. Therefore it is better to use a for loop with a numeric index (or Array.forEach or the for...of loop) when iterating over arrays where the order of access is important.
回答3:
for-in loop enumerates on the enumerable properties of a variable. For your array, "0", "1" and "4" are added as enumerable property on the array. Therefore, for-in loop only gets 0, 1 and 4 in "i".
for loop works with the i = 0 to 5. so you try to access values at 2 and 3 as well which obviously are undefined.
回答4:
The syntax
for (var k in obj)
is actually a for-each loop. It iterates through the properties of an object. You should familiarize yourself with JavaScript objects. An object is map of keys to values.
So, the for-each loop can be very useful with objects. But, when looping through an array, it's better to use a regular for loop.
Here is an example of a for-each loop used on the properties of an object: http://jsfiddle.net/nbtLpw0z/.
回答5:
I am useing for-in loop because it is a shorter form, but sometimes you may want to have control over the iteration variable. For instance, if you want to iterate over even indices, you'd need to use the normal for loop:
for (var i = 0; i < myarray.length; i+=1) {...}
The same applies, for example, if you want to iterate backwards:
for (var i = myarray.length-1; i >= 0; i--) {...}
Certainly, for objects, the for-in loop allows you to get the property name in the iteration variable.for ex.
var obj = {year: 2014, city: "Surat"}
for (var propn in obj) alert(propn + " = " + obj[propn]);
In your example, I'd use for-in because you are doing a simple iteration. Moreover I think in a non-optimized Javascript compiler/interpreter, the for-in loop would be even faster because variable increment is done internally.
回答6:
For starters there is no point is using a for in
loop on an Array because arrays in JavaScript can only have ordered, numeric indexes. So you can access the array at any index between the range of 0
and array.length - 1
Alas, if you wanted to use a for in loop to iterate over an array you certainly can, however, a regular for loop is more appropriate.
A for in
loop is used when you don't have ordered numeric indices. JavaScript objects are really an ordered hash table. You can access keys of JavaScript objects with the in
operator which returns the key for the object, and by accessing the object at that key you can get the value.
For example:
var obj = {
hello: "world",
world: "hello"
};
A regular for loop wouldn't work, so you would need t use a for in
loop.
for(var i in obj) console.log(obj[i]);
Objects also don't return a length property that is accurate enough to iterate over the entire object, so a for in
loop is absolutely necessary.
Also note that by assigning values to the array not in the order in which the next free element would exist will automatically place undefined
in the elements that you skipped.
In your example, the array would look like this:
[0, 1, undefined × 2, 4]
回答7:
for-each
loop is recommended for traversing object properties, whereas for
loop is recommended for arrays. In your case you can use push()
to get same results.
var a = []; //recommended way of declaring arrays over `new Arrays()`
a.push(0);
a.push(1);
a.push(4);
//usual for-loop
for (var i = 0; a.length > i; i++) //recommended
console.log('a[', i, ']=', a[i]);
console.log('---------------------');
// for-each loop
for (var k in a) //not recommended
console.log('a[', k, ']=', a[k]);
console.log('---------------------');
Open console...
var person = {
'name': 'Adam'
};
for (var k in person)
console.log('person.' + k, '=', person[k]);
console.log('----------------------');
person.age = 26; //new property
for (var k in person)
console.log('person.' + k, '=', person[k]);
console.log('----------------------');
person['gender'] = 'Male'; //again a new property
for (var k in person)
console.log('person.' + k, '=', person[k]);
console.log('----------------------');
person.name = 'Will'; //updating property
for (var k in person)
console.log('person.' + k, '=', person[k]);
console.log('----------------------');
Open console...
回答8:
Under the hood the for-in loop is nothing but a for loop. For(i in x) is broken down in to -
for(i=0;i<x.length;i++) {
if(x[i] != undefined)
console.log(x[i]);
}
回答9:
I've read and heard that normal for loops: for(var i = 0; i < arr.length; i++)
is faster. But I'd say use for of
:
var arr = [1,2,3], obj = {x: 1, y:2};
for(var value of arr) console.log(value) // 1, 2, 3
for(var key in obj) console.log(key) // x, y
for(var key of Object.keys(obj)) console.log(key) // x, y
you can use Object.keys(obj)
to convert the object's keys to an array and call Array.prototype
methods on it
回答10:
Your "for" loop looks at all the values of the indices of the array from 0-4, as that is exactly what you are asking it to do. So it takes a look at a[0] and finds a value, then a[1] (same deal), then it goes to a[2] and realizes that you never initialized a value for a[2], therefore it's undefined. Same goes for a[3], and finally a[4] has a value so it finds it.
That type of "for" loop will check every index whether defined or not.
A "for ... in ..." loop will only check initialized values. Your array has 3 values that have been initialized, therefore it checks those. It will show them to you in the order of their indices, but the indices don't actually affect what it's looking at. So if you changed your "a[1]" to "a[3]" and "a[4]" to "a[10]", you'd still get the exact same answer when you use a "for ... in ..." loop.
来源:https://stackoverflow.com/questions/27683259/difference-between-for-loop-and-for-in-loop-in-javascript