Array.fill repeats the same object. What for?
var arr = new Array(4).fill({});
arr[2].status = true;
console.log(arr[0].status);
why is filling the array filling the same object at all indices?
source to share
.fill
will insert the same exact object (same instance) into every segment of the array. That is why it .fill(Math.random)
returns an array always filled with the same number.
You can do this to get what you want:
new Array(4).fill().map(() => ({}));
To explain what's going on under the hood in your question code, let me convert it to ES5 code:
var arr = new Array(4); // new Array(4)
var obj = new Object(); // *1: with this object instance
for(i = 0; i < 4; i++) { // .fill( *1 )
arr[i] = obj;
}
As you can see, we are assigning one object instance ( obj
) to each cell of the array instance.
This is the same principle why:
const obj = {};
const a = obj;
const b = obj;
a.foo = true;
Makes a a.foo === b.foo
resolution true
.
source to share
fill
repeats the value that you pass. The value in this case is an object reference. Each copy of this link refers to the same object, so you end up with:
+ βββββββββ + arr βββ> | (array) | + βββββββββ + + | 0 | ββ + - + - + -> | (object) | | 1 | - / / / + ββββββββββββββ + | 2 | ββ / / | status: true | | 3 | βββ / + ββββββββββββββ + + βββββββββ +
If you want separate objects, you need to create multiple objects. The easiest way, of course:
var arr = [{}, {}, {}, {}];
Example:
var arr = [{}, {}, {}, {}];
arr[2].status = true;
console.log("arr[0].status", arr[0].status);
console.log("arr[2].status", arr[2].status);
If you want to do it with variable length:
Since you are using Array.fill
, I assume you are using ES2015 (aka "ES6") features (but see below for an ES5 compliant solution without polyfills). You can do it via Array.from
with a callback:
const arr = Array.from({length:4}, () => ({}));
arr[2].status = true;
console.log("arr[0].status", arr[0].status);
console.log("arr[2].status", arr[2].status);
This gives you:
+ βββββββββ + arr βββ> | (array) | + βββββββββ + + | 0 | ββββββββ> | (object) | | 1 | βββββ + + ββββββββββββββ + | 2 | βββ + | | 3 | - + | | + ββββββββββββββ + + βββββββββ + | | + ββ> | (object) | | | + ββββββββββββββ + | | | | + ββββββββββββββ + | + ββββ> | (object) | | + ββββββββββββββ + | | status: true | | + ββββββββββββββ + | | + ββββββββββββββ + + ββββββ> | (object) | + ββββββββββββββ +
(You can do this with an Array.from
ES5 polyfill if you want, just use function() { return {}; }
instead () => ({})
.)
In ES5, if you want variable length, the simplest thing is probably just a loop:
var arr = [];
for (var i = 0; i < 4; ++i) {
arr[i] = {};
}
arr[2].status = true;
console.log("arr[0].status", arr[0].status);
console.log("arr[2].status", arr[2].status);
You can of course add this to a helper function.
source to share