6

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.

5
  • [,,].forEach(console.log.bind(console, 'Log: ')) also seems broken :) Commented May 27, 2016 at 19:50
  • But Array.apply(null, new Array(5)).forEach(console.log.bind(console)) ok Commented May 27, 2016 at 20:00
  • This is the same as JavaScript “new Array(n)” and “Array.prototype.map” weirdness, but with forEach. Commented May 27, 2016 at 20:05
  • That question helps explain some of the strangeness, but doesn't illuminate the reason why forEach fails to iterate at all, as opposed to map which does iterate, but has unexpected values. Commented May 27, 2016 at 20:15
  • It's the same problem, map is not iterated neither: Array(5).map(function(){ alert("You won't see me") }) Commented May 27, 2016 at 23:00

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

can't you add short explanation here, about what he say?
If you use JSON.stringify() on the new Array object, you should get a sequence of nulls. I think that is worth noting.
3

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); });

Comments

2

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

7 Comments

Sorry, I noticed the typo and fixed it. The problem still exists, however.
just a typo. issue is there.
Updated the answer. For each skips over undefined properties
Knew it was forEach! Thanks for doing the legwork and looking the details of it up.
Array.map seems to have similarly strange behavior, running arr.map(function(v, i) { return i; }); returns [undefined x 5] rather than the proper indices. Whereas running the same map call on an array literal with undefined works as expected. This leads me to believe it's an issue with the Array constructor array, not just the array methods themselves.
|
-1

I suspect that this may have to do with intricacies of the Javascript foreach loop, not the Array(int) constructor. Using a normal for loop:

for(var i = 0; i < arr.length; i += 1) {
  console.log(arr[i] + " " + i);
}

produced the desired result.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.