Array.prototype.fill() with object passes reference and not new instance
You can first fill
the array with any value (e.g. undefined
), and then you will be able to use map
:
var arr = new Array(2).fill().map(u => ({}));
var arr = new Array(2).fill().map(Object);
JavaScript - why Array.prototype.fill actually fills a pointer of object when filling anything like 'new Object()'
I am wondering why it's happening?
Array#fill
takes the value you give it as the first argument, and fills the array with copies of that value.
The value you're giving it is a reference to an array, so naturally what it gives you back is an array filled with copies of that reference. Not copies of the array, copies of the reference.
E.g., it behaves this way for exactly the same reason this code:
var a = new Array(10);
var b = a;
...leaves us with a
and b
both referring to the same array (both containing the same value; a reference to the single array we've created).
Let's throw some Unicode-art at it:
After this code runs:
var a = new Array(10);
var b = a;
we have this in memory (minus a few irrelevant details):
a:Ref89895−−−+
|
| +−−−−−−−−−−−−−−−+
+−−−−−>| array |
| +−−−−−−−−−−−−−−−+
| | length: 10 |
b:Ref89895−−−+ +−−−−−−−−−−−−−−−+
a
and b
contain a reference, which I've shown here as Ref89895 although we never see the actual value. That's what's copied by b = a
, not the array itself.
Similarly, when you do:
var matrix = new Array(10).fill(new Array(10), 0);
you end up with
+−−−−−−−−−−−−−−−+
matrix:Ref89895−−−>| array |
+−−−−−−−−−−−−−−−+
| length: 10 |
| 0: Ref55462 |--\
| 1: Ref55462 |--\\
| 2: Ref55462 |--\\\
| 3: Ref55462 |--\\\\ +−−−−−−−−−−−−−−−+
| 4: Ref55462 |---+++++->| array |
| 5: Ref55462 |--///// +−−−−−−−−−−−−−−−+
| 6: Ref55462 |--//// | length: 10 |
| 7: Ref55462 |--/// +−−−−−−−−−−−−−−−+
| 8: Ref55462 |--//
| 9: Ref55462 |--/
+−−−−−−−−−−−−−−−+
To create a 10-place array where each of the 10 places is itself a 10-place array of 0, I'd probably use either Array.from
or fill
with map
:
// Array.from
var matrix = Array.from({length: 10}, function() {
return new Array(10).fill(0);
});
// fill and map
var matrix = new Array(10).fill().map(function() {
return new Array(10).fill(0);
});
or in ES2015:
// Array.from
let matrix = Array.from({length: 10}, () => new Array(10).fill(0));
// fill and map
let matrix = new Array(10).fill().map(() => new Array(10).fill(0));
Array.fill(Array) creates copies by references not by value
You could use Array.from() instead:
Thanks to Pranav C Balan
in the comments for the suggestion on further improving this.
let m = Array.from({length: 6}, e => Array(12).fill(0));
m[0][0] = 1;
console.log(m[0][0]); // Expecting 1
console.log(m[0][1]); // Expecting 0
console.log(m[1][0]); // Expecting 0
Why does Array(n).fill([]) not the same as hardcoding the array or using a for loop to create that array?
as described here
the fill
method of Array
fills the array (or a given range of indices in the array) with the same value
that means when you write the line Array(3).fill([])
it actually puts the same array created using []
in all the indices of the array, so editing the array in one place, affects all indices (since they all point to the same array []
)
How do I use array.fill for creating an array of objects?
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))
Array.prototype.fill({}) references
You are filling each position in the array with the same reference of an object, it is the same as
let a = {};
const b = a;
a.hi = 'hi';
console.log(b);
What am I missing in this Javascript Array behavior?
function na(){
return Array(2).fill(Array(2))
}
na()
fills the empty Array(2)
with shallow copies
of the second Array(2)
object.
As a result changing values in any of the clones changes the Array's value everywhere.
a = Array(5).fill(Array(3))
a[0][0] = 1
a[0][1] = 2
a[0][2] = 3
console.log(JSON.stringify(a))
Related Topics
How to Add a Delay in a JavaScript Loop
How to Remove a Property from a JavaScript Object
JavaScript Post Request Like a Form Submit
How to Obfuscate (Protect) JavaScript
Simplest Code For Array Intersection in JavaScript
How to Set/Unset a Cookie With Jquery
Error: Can't Set Headers After They Are Sent to the Client
Uncaught Referenceerror: $ Is Not Defined
How to Create a File in Memory For User to Download, But Not Through Server
What Is the 'New' Keyword in JavaScript
How to Manage a Redirect Request After a Jquery Ajax Call
Weird Behavior With Objects & Console.Log
JavaScript by Reference Vs. by Value