Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use forEach to loop over Array(n), array of undefined values [duplicate]

I'm want to quickly construct an array of n length using the array constructor Array() and then loop over the resulting array.

Per MDN's docs:

If the only argument passed to the Array constructor is an integer between 0 and 232-1 (inclusive), this returns a new JavaScript array with length set to that number. If the argument is any other number, a RangeError exception is thrown.

Presumably, executing Array(5) creates an array with a length of 5, which it does.

var arr = new Array(5);

console.log(arr); // [undefined x 5]
console.log(arr.length); // 5

However, when I try to loop over the resulting array and log out the values or the index, nothing happens.

arr.forEach(function(v, i) { console.log(v, i); });

// nothing logs to the console

Alternatively, if I use an array literal, and try to loop over the values, it logs as expected:

[undefined, undefined].forEach(function(v, i) { console.log(v, i); });

// undefined 0
// undefined 1

Why can't I loop over an array created by the Array constructor?


This answer explains some of the browser strangeness that occurs with map, example:

arr.map(function(v, i) { return i; }) // returns [undefined x 5]

But I'm particularly interested in why the forEach loop doesn't iterate at all over the values.

like image 805
Himmel Avatar asked May 27 '16 19:05

Himmel


3 Answers

I understand I am not answering to the question directly, bit still I believe this provides good information.

Check what Kyle Simpson said recently about this topic.

Basically,

console.log(new Array(5))  // Chrome: [undefinedx5] Firefox: [ <5 empty slots> ]

and

console.log([undefined, undefined, undefined, undefined, undefined]) // [ undefined, undefined, undefined, undefined, undefined ] 

are entirely different value types. And the browser is (kind of) lying to you when it says undefinedx5. Applying .map() over the first case will return nothing, while in the second case you can do operations with the undefined.

From the spec, ecma-262/5.1/#sec-15.4.2.2, the only thing new Array(5) does, is to create an object of class type Array with length property = 5. The literal array syntax, [], actually places the types (if you give it something) in the slots.

like image 74
VRPF Avatar answered Nov 09 '22 20:11

VRPF


That's because ES5 array methods skip missing indexes. That is, they iterate i from 0 to length-1, but at each iteration they check if the array has an i own property.

If you want it to work, you can use fill to create the indices.

var arr = new Array(5).fill();
arr.forEach(function(v, i) { console.log('arr['+i+'] = ' + v); });
like image 37
Oriol Avatar answered Nov 09 '22 20:11

Oriol


Looks like you have a typo in your code:

arr.forEach(functio(v, i) {

Use this instead:

arr.forEach(function(v, i) {

UPDATE

forEach() executes the provided callback once for each element present in the array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized (i.e. on sparse arrays). MDN article

like image 38
e_i_pi Avatar answered Nov 09 '22 20:11

e_i_pi