Why the with() method of JavaScript Array is a gem?

Why the with() method of JavaScript Array is a gem?

Discover the new with() method in JavaScript Arrays from ECMAScript 2023 with examples and use cases.

Featured on Hashnode

JavaScript array methods offer plenty to web developers already. The methods like map(), reduce(), filter() , some(), every(), and many more have helped build our JavaScript muscles for better logic and algorithms.

The with() method is a relatively new inclusion to the JavaScript array method list, and its only intention is to change the value of a given index in an array in the "immutable" way. A big deal? Yes! Let's learn.

Btw, please do not confuse the with() method from the JavaScript Array with the with statement from the language. The with statement has been deprecated whereas, the with() method is a new inclusion to the language. People say JavaScript is weird, naming things is possibly a reason for it!

This article is also available as a video tutorial now. You can check it out here:

The traditional way to seek and change

Let us consider an array of numbers,

const numbers = [1, 2, 3, 4, 5];

How would you change the element of an array for a given index? Suppose you need to change the element 3 which is at the index 2(remember, the array index in JavaScript starts with 0) with a new element, say, 6.

The usual instinct would be to do this,

numbers[2] = 6;

console.log(numbers); // [1, 2, 6, 4, 5];

This works! However, there is a problem. We have mutated(aka, permanently changed) the original array. When you deal with data in your application, a data structure like an array should hold the original(unchanged) data as a "source of truth". You wouldn't want it to be modified by any functions and logic to achieve better predictability in your code.

Immutability is a great tool

Immutability is a mechanism to ensure that we can not change something(an array, object, etc). However, if we need a modified version of it, we need to first create a copy of the original and then make modifications to the copied version. This ensures that the original data is never changed by anything in the application, knowingly or unknowingly.

So, how about changing the element of an array at a given index, in an immutable way? It means every time we change an element in an array, we do not mutate the original array, rather we get back a new copy of the original array with the change applied.

The with() method and immutability

ECMAScript 2023 introduced a new method called with() to solve this problem of mutability and achieve immutability while changing an element of an array. So now, instead of using a given index on the array directly, we can use the with() method to change the element value.

The with() method takes two parameters:

  • index - An index value which can start from 0, and also can be a negative number. The negative index counts backwards from the end of the array.

  • value - The value to change at a given index.

Let us now apply the with() method on the same array to change the element at a given index,

const numbers = [1, 2, 3, 4, 5];

const newArray = numbers.with(2,6);

console.log(numbers); // Unchanged => [1, 2, 3, 4, 5];
console.log(newArray); // Changed(A new copy) => [1, 2, 6, 4, 5];

As you see, the with() method produces a new copy of the original array with the change applied. The original array is unchanged.

The with() method and the negative index

One more drawback of the direct index-based element seeking to get an element at a given index is that you can not use the negative number as an index value. Try something like the code snippet below, you will get an undefined.

numbers[-2]; // undefined

Also, trying to set a value on a negative index will have unexpected results,

const numbers = [1, 2, 3, 4, 5];
numbers[-2] = 8;

console.log(numbers); // [1, 2, 3, 4, 5, -2: 8]

Did you see that? You have ended up adding something completely different than what you anticipated. But, using the with() method, you can change an element of an array at a negative index. The negative index starts from the end of the array with an index value of -1 and move backwards.

const numbers = [1, 2, 3, 4, 5];

const anotherArray = numbers.with(-2, 8);
console.log(anotherArray); // [1, 2, 3, 8, 5]

In the above code, we have changed the second element of an array from the end. Hence the element 4 in the array is replaced with the element 8.

You can use the at() method of JavaScript array to read an element using a negative index.

anotherArray.at(-2); // 8

Method chaining

As the with() method returns an array, you can chain the output of the with() method along with other array methods, like map(), filter(), reduce(), etc.

In the code snippet below, we replace the second element of the ages array with a new element, and then map the output array to multiply each element by four.

const ages = [12, 23, 56];

const mappedAges = ages.with(1, 32).map(x => x * 4);

console.log(mappedAges); // [48, 128, 224]

Can you please give a real-life use case of the with() method?

Sure! When I published a YouTube video on this topic, I got a question about the real-life use case of the with() method. The exciting thing is, that I discovered the with() method when I was building a use case that needs the feature it offers. The image below provides a summary of the use case.

JavaScript Array with() method use case


That's all for now. I hope you agree with me that the with() method is a true gem providing us immutability and negative index accessibility with JavaScript Arrays. You can check out these articles to learn more about JavaScript arrays and their unique use cases:

Liked it? Please let me know with your comments and likes. ❤️

Let's connect. I share knowledge on web development, content creation, Open Source, and careers on these platforms.

Did you find this article valuable?

Support Tapas Adhikary by becoming a sponsor. Any amount is appreciated!