Reputation: 1036
In the following javascript snippet, why are elements in tedious
and concise
not equivalent when you run this snippet?
I get /**ref:2**/
output for concise
from the second element.
const tedious = [
{},
{},
{},
{},
{},
{},
{},
{},
{},
];
const concise = new Array(9).fill({});
console.log(tedious);
console.log(concise);
Upvotes: 8
Views: 7243
Reputation: 1
Note: not sure what is happening in running a snippet, but that ref business does not happen in the real world
as per Xufox comment:
/**ref:2**/
means “reference to element 2 of the array”, since the console feature of Stack Snippets can’t know whether you’ve got an infinitely nested structure, so instead the ref comments (and id comments which aren’t used in this case) are used
The real problem with
const concise = new Array(9).fill({});
IS that all 9 entries will "refer" to the same object - see the output
const concise = new Array(9).fill({}); // {}
concise[0].a='hello world';
console.log(JSON.stringify(concise))
To better illustrate that, let's pass a non-empty object to fill
with a random value
const concise = new Array(9).fill({random:Math.floor(Math.random() * 1000)});
console.log(JSON.stringify(concise))
Clearly, that object is created exactly once
Try
const concise = new Array(9).fill(0).map(() => ({}));
concise[0].a='hello world';
console.log(JSON.stringify(concise))
as the map callback is called once for each element, a new object is created each time
Or you can try
const concise = Array.from({length:9}, () => ({}));
concise[0].a='hello world';
console.log(JSON.stringify(concise))
the second argument to Array.from
is a callback that is called once for each element, it's basically the same .map
And of course, thanks to @Slai, the above is even more simply
const concise = Array.from({length:9}, Object);
Compare the output of the "math random" code above with
const concise = Array.from({length:9}, () => ({random:Math.floor(Math.random() * 1000)}));
console.log(JSON.stringify(concise))
Upvotes: 13