Let's say I have
myArray = ['item1', 'item2']
I tried
for (var item in myArray) {console.log(item)}
It prints 0 1
What I wish is to have item1 item2
Is there any other syntax that works without using
for (var i = 0; i < myArray.length; i++)
You can use Array.forEach
var myArray = ['1','2',3,4]
myArray.forEach(function(value){
console.log(value);
});
forEach() (after I answered here) in the comment for another answer.myArray[123] = '6' you will get a totally different result using Array.forEach than when using for (var i = 0; i < myArray.length; i++) syntax.map() wouldn't be the appropriate analog.What you probably want is for...of, a relatively new construct built for the express purpose of enumerating the values of iterable objects... as distinct from for...in, which enumerates property names (presumably1 numeric indices in the case of arrays). Your loop displayed unexpected results because you didn't use the property names to get the corresponding values via bracket notation... but you could have.
const array = ["a","b","c","d"];
for (let value of array) {
console.log(value);
}
for (let propertyName in array) {
let value = array[propertyName];
console.log("propertyName: %o, value: %o", propertyName, value);
}
<!------------------------------------------------------------------------------><script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script><script>console.config({timeStamps:false,maximize:true})</script>
1 Unfortunately, someone may have added enumerable properties to the array or its prototype chain which are not numeric indices... or they may have assigned an index leaving unassigned indices in the interim range. The issues are explained pretty well here. The main takeaway is that it's best to loop explicitly from 0 to array.length - 1 rather than using for...in.
To address your comment (emphasis mine):
[...] why do I need to calculate the size of an array whereas the interpreter can know it[?]
Array.length is not calculated on the fly; it's updated whenever the length of the array changes. You're not going to see performance gains by avoiding it (apart from caching its value rather than repeatedly accessing the property). Here's a test of various constructs used to perform a sum operation on an array of 1,000 numeric elements (bigger bars are better).
Feel free to fork the test and try different inputs, methods, etc.
for (let i in myArray) {} results in i being a string type, NOT a number type, so they are not totally "numeric" indices.i is a poor variable name when used in a construct which explicitly assigns a property name to that variable. The documentation should make that clear -as should the multiple instances of the term property name in the post above.In ES5 there is no efficient way to iterate over a sparse array without using the length property. In ES6 you can use for...of. Take this examples:
'use strict';
var arr = ['one', 'two', undefined, 3, 4],
output;
arr[6] = 'five';
output = '';
arr.forEach(function (val) {
output += val + ' ';
});
console.log(output);
output = '';
for (var i = 0; i < arr.length; i++) {
output += arr[i] + ' ';
}
console.log(output);
output = '';
for (var val of arr) {
output += val + ' ';
};
console.log(output);
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="//gh-canon.github.io/stack-snippet-console/console.min.js"></script>
All array methods which you can use to iterate safely over dense arrays use the length property of an object created by calling ToObject internaly. See for instance the algorithm used in the forEach method: http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18
However in es6, you can use for...of safely for iterating over sparse arrays.
See also Are Javascript arrays sparse?.
This is the natural javascript option
var myArray = ['1','2',3,4]
myArray.forEach(function(value){
console.log(value);
});
However it won't work if you're using await inside the forEach loop because forEach is not asynchronous. you'll be forced to use the second answer or some other equivalent:
let myArray = ["a","b","c","d"];
for (let item of myArray) {
console.log(item);
}
Or you could create an asyncForEach explained here:
https://codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404
Use Iterators...
var myarray = ['hello', ' hello again'];
processArray(myarray[Symbol.iterator](), () => {
console.log('all done')
})
function processArray(iter, cb) {
var curr = iter.next()
if(curr.done)
return cb()
console.log(curr.value)
processArray(iter, cb)
}
More in depth overview: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
Use the built-in Javascript function called map. .map() will do the exact thing you're looking for!
forEach() would be the more direct match than a function which creates a new array...
forloop or the.forEach()function?for (var propertyName in myArray)would make the issue with the observed behavior more clear. In any case, for a higher-order construct, seeArray.forEachbut note it has a number of implications that make it different from either of the above forms. (The differences between the forms are covered by many duplicates.)lengthdoesn't "calculate" the size of the array. The length of an array is an intrinsic value of the Array type.lengthwas calculated, you could just cache it:for (var i = 0, length = arr.length; i < length; i++)