Recently, I came across the following code snippet:
const arr = new Array(2).fill([]) arr[0].push(1) arr[0] === arr[1] // true or false?
The correct answer is true.
Both elements at indexes 0 and 1 contain the same mutable value - empty array which was passed as an argument the the method.
See the description from the ECMAScript specification:
Array.prototype.fill() expects in its first parameter an already defined value and then just set the same value as "number"-keyed property values (step 11b).
This definitely sounds like a challenge for JS geeks. Is it possible to use Array.prototype.fill() in such a way that each element in the resulting array has its own empty array?
Something like that:
const arr = new Array(2).fill([]) arr[0].push(1) arr[0] === arr[1] // false arr[0].length //1 arr[1].length //0
To achieve this, I’d use the insight provided by step 11b from the specification:
b. Perform ? Set(O, Pk, value, true).
That statement is straightforward: it sets the value (value) of a specific property key (Pk) of an object (O). JavaScript has a feature that can intercept and redefine fundamental operations for that object. It's called a Proxy!
Let's use a Proxy object and redefine an array set operation to solve our challenge:
const handler = { set(obj, prop, value) { //assign a new "instance" of empty array to the properties obj[prop] = [...value] return true }, } // Proxy cracks the challenge! const arr = [...new Proxy(Array(2), handler).fill([])]; arr[0].push(1) arr[0] === arr[1] // false arr[0].length //1 arr[1].length //0
Solved!
Top comments (0)