Setting without modifying the original array
Let’s start with the use case.
In the past, when we wanted to modify an array item, we typically used the index value. For example, changing the second item in the array to a movie title, such as ‘Inception’:
const arr = ['Captain America: The First Avenger', 'Captain America: The Winter Soldier', 'Captain America: Civil War', 'Captain America: Brave New World'];
arr[1] = 'The Avengers';
However, this kind of modification will change the original array.
If we want the original array to remain unchanged, in the past, we used to first create a copy of the array and then make the changes.
There are several ways to copy an array, and the following methods all work:
const fruits = ["Apple", "Mango"];
const fruitsCopy = [... fruits]
const fruitsCopy2 = Array.form(fruits)
const fruitsCopy3 = fruits.slice()
const fruitsCopy4 = fruits.concat()
Personally, I prefer using the slice()
method. It has good semantics and excellent compatibility. Here’s how you can use it:
const arr = ['Captain America: The First Avenger', 'Captain America: The Winter Soldier', 'Captain America: Civil War', 'Captain America: Brave New World'];
const arr2 = arr.slice();
arr2[1] = 'The Avengers';
Now, you can use the with() method
Nowadays, there’s no need to go through the hassle of copying the array. We now have a dedicated API method to copy the array and set its item values: the Array.prototype.with() method. Here’s how to use it:
const arr = [, 'Captain America: The Winter Soldier', 'Captain America: Civil War', 'Captain America: Brave New World'];
// result is ['Captain America: The First Avenger', 'Captain America: The Winter Soldier', 'Captain America: Civil War', 'Captain America: Brave New World']
console.log(arr.with(0, 'Captain America: The First Avenger'));
Syntax and compatibility of with
The syntax of the with method is as follows:
arrayInstance.with(index, value)
Here:
index is the index value, which can be negative (the final index value is calculated as negative number + array length). The meaning of this parameter is the same as the at() method of arrays. If the index value is out of range, an error will occur, so keep that in mind. value is simply the value to modify. If this parameter is not set, the corresponding array item will become undefined. In general, the current best practices for web development recommend using the at() method for reading array values and with() for setting values. These methods complement each other.
Compatibility
Supported around 2023, and all modern browsers support it. For details, see the screenshot from Can I Use below:
Other methods that preserve the original array
In addition to with()
, there are several other methods that also preserve the original array while performing related array operations, such as reversing, sorting, and slicing.
These include:
toReversed()
: Does not modify the original array but reverses the array and returns a new array. The method that reverses the original array is reverse(), and they share the same parameters.toSorted()
: Does not modify the original array but sorts the array and returns a new array. The corresponding method for modifying the original array is sort(), with the same parameters.toSpliced()
: Does not modify the original array but allows slicing and insertion operations, returning a new array with the changes. The old method is splice(), with similar parameters.
In React and Vue development, sometimes it’s necessary to manipulate arrays without modifying the original array (to avoid triggering automatic re-renders). These methods are worth considering.
These methods were supported around the same time in browsers, so their compatibility is the same.