Scenario: In the development, I want to change a one-dimensional array into a two-dimensional array, the code is as follows:
let arr = new Arrary(3).fill([])
let brr = ['1'.'2'.'3']
brr.forEach((item,index) = >{
arr[index].push(item)
})
console.log(arr)
Copy the code
The desired effect is as follows:
After what looks like a “nice” operation, the output is
The constructor: let arr = new Array(3) declares an Array of length 3, and fills the newly generated Array with three empty arrays using fill () to create a two-dimensional Array. Then we define three strings in an array, 1,2, and 3, and iterate over the BRR, so that each element in the BRR is pushed into each empty array in the two-dimensional array. The desired effect is achieved, but the reality is very boring. Finally, each array object in the two-dimensional array is pushed into three elements.
If you want to dynamically change the value of one of the items in the array, you will find that the value of the entire array changes. This is because you ignored one caveat of this method:
If the type of the fill is an object, then the object is assigned to the same memory address, not the deep-copy object.
This means that the object is populated, so all the objects to be populated point to the same address. So here we need to make a deep copy of arR and then modify its value.
Deep copy processing
let arr = new Array(3).fill([])
let brr = ['1'.'2'.'3']
let crr = JSON.parse(JSON.stringify(arr))
brr.forEach((item, index) = > {
crr[index].push(item)
})
console.log(arr,'arr')
console.log(crr,'crr')
Copy the code
If the expression is not clear, here is a paragraph of explanation borrowed from the big guy:
To create a two-dimensional empty array, fill takes the first parameter as value and fills each item in the array. By implication, the value is not created every time, just arr[0]=value, arr[1]=value and so on until the last item. (of course, the second and third parameters can control the starting position.) Map is the result of each run of the function, forming a new array. Returns a new array. Why? That’s the nature of language. It’s functional programming that gives you the illusion that what’s in parentheses is going to be run multiple times. Of course, fill can also create this value multiple times. However, it’s actually more intuitive to create it once and wait for the rest (pointer references). For performance. You think, if it’s a nested object, the first layer does the copy, the second layer should do it. What about the third layer? What if it’s a ring? Also, fill doesn’t know what you’re passing, because the array is a reference type. Again, fill receives a value, not a function.
Summary: Fill can be regarded as a shallow copy of the data if it references the data type. Each time it fills a reference to the address of the target object. The value of push traversed with foreach is always the same object in the heap. In general, array.fill is more suitable for simple data types.
For deep and shallow copies refer to:
- Js deep copy vs shallow copy
- 【JS】 The difference between deep copy and shallow copy, several methods to achieve deep copy
- Deep copy and shallow copy in javascript?