I was reading Trailing commas and .forEach()
documentations on MDN meanwhile playing with arrays.
So let's imagine a scenario when you have an array with elements like Number
, undefined
and created ones with trailing commas and running a forEach()
on that. See from the documentation:
forEach()
calls a provided callback function once for each element in an array in ascending order. It is not invoked for index properties that have been deleted or are uninitialized.
Based on that it skips the elements created with trailing commas but not the undefined
ones:
const array = [ 1, 2, , 4, , undefined, ];
console.log({ length: array.length }); // shows 6
array.forEach((e, i) => console.log({e, i})); // logging 4 elements
In the same time using traditional for
loop it logs all the elements as expected:
const array = [ 1, 2, , 4, , undefined, ];
console.log({ length: array.length }); // shows 6 as before
for (let i = 0; i < array.length; i++) {
console.log({e: array[i], i}); // logs 6 elements
}
Also Chrome developer tool is showing empty items for the array for ones created by trailing commas:
My questions:
From the documentation I found .forEach()
is skipping deleted or uninitialized elements when iterating. So I see that statement, that's how it has been built.
So my questions would be:
- What's the difference between the
undefined
directly added to the array and by the trailing commas? - Why
.forEach()
is showing up oneundefined
which has been added but not all the other ones. - How can you differentiate from items called empty and
undefined
in this term?
What is going on under the hood? Can someone enlighten me about this scenario?
Appreciate the clarification, thank you!
Update:
I think I understood after further reading based on the linked questions.
So I took a look how .forEach()
has been implemented which has an extra check with in operator for each elements and that's the difference. See as the following:
const array = [ 1, 2, , 4, , undefined, ];
console.log({ length: array.length }); // shows 6 as before
for (let i = 0; i < array.length; i++) {
console.log({e: array[i], i, has: i in array});
}
So for the directly added undefined
element the i in array
returns true
for all the empty elements false
which makes sense now. As a result .forEach
only calls the callback once the current element is existing.
Thanks for all the comments!