Avoid data mutation with the powerful spread operator(…)

An introduction to spread operator(…) for beginner....

JavaScript is a very powerful programming language, and over the years it has proven to be so. From been a language of the browser to a programming language use for server side scripting with NodeJS; mobile development with React native; desktop development with Electron….

As JavaScript evolves, new version of the language has brought big changes or features to the language. ES2015, or popularly known as ES6, for instance brought huge changes to the language, and one of the coolest features among others is the spread operator(…). We'll focus on spread operator and the power in wield, esp. how it replaces some Array method to mutate data.

Data mutation is done in all of the applications you'll ever use. data mutation, to put simply, is the changing of the content of a data structure. when we add or remove an item from a data structure we have mutated the data. so, if we use array.pop(), array.push(), array.shift() we'd have change the original size of the data structure. while data mutation is unavoidable when building an application, it is very imperative that we reduce the practice because it is bug-friendly. For example: we have an array of colors and we want to add a new color and remove the last color, and later remove the first color from the array.

let colors = ['green', 'yellow', 'blue', 'red'];

colors.push('purple');
console.log(colors); // ["green", "yellow","blue","red", "purple"]

colors.pop();  // ["yellow", "blue", "red"]
colors.shift();  // ["yellow", "blue", "red","blue"]
console.log(colors);

let's analyze the above code samples and see why we should avoid data mutation. using Array.push() we add the "purple" color and our colors array increased by one. we then use Array.pop() to remove the last color in our colors array. Array.shift() is use to remove an item from the beginning of an array. in this example we have mutated or make changes to the Array of colors. Our array of colors in this case has changed. If we want implement a ew feature to our application using the original colors array, let say we want to filter out some colors or maybe sort the colors it by alphabet, would we still have access to the original colors array? the answer is NO, cause it has be mutated, the content has changed. To solve this, we could just assign the value of the colors array to a new array and mutate or make changes to the new colors array. now lets use the Spread operator solve this mutation problem

Replace Array.unshift(), Array.push() with the Spread operator(…)

Array.Unshift() adds an item to the start of array; while Array.push() adds an item to end of an array. let's see how we can replace this with spread operator(…)

let colors = ["green", "yellow", "blue", "red"];
function addColor() {
    return [...colors, "purple"];
}
 ["green", "yellow", "blue", "red", "purple"]

function addColor2() {
    return ["purple", ...colors];  ["green", "yellow", "blue", "red", "purple"]
}

In the first code sample we added the new color to the start of the colors array, and in the second code sample we added a new color to the end of the colors array. What did you notices? the spread operator creates a new array and adds the new colors to the new array without changing the original colors array. so we can still use the original colors array. The above is a pretty basic example but you get the idea. let replace Array.splice() with the combination of Array.slice() and the spread operation to remove an item in an array.

A simple approach to removing item from an array with the spread operator.

Example: I have an array of Udemy JavaScript instructor I like the most, and I want to remove each instructor from the instructors array by their names.

let instructors = ['Jonas', "Stephen Grider", "John Smiga", "Brad Traverse", "Maximillian", "Ninja Code"];

function removeInstructor(arr, name) {
   let newArray = [];
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] !== name) {
           newArray.push(arr[i]);
         }
     }
     return newArray;
 }
 let check = removeInstructor(instructors, "John Smiga");

Our first approach works and looks good but there is a problem: the original instructor array has changed and we can not get access to the original instructors array. let's look at the another approach using the spread operator with Array.slice() method. We could have use the array.splice() but it would've make no difference.

function removeInstructor(arr, name) {
    return [...arr.slice(arr.indexOf(name), 0), ...arr.slice(arr.indexOf(name) + 1)];
}
 let check = removeInstructor(instructors, "John Smiga");

This approach looks simple and readable, and most importantly in doesn't mutate or change the original instructors array. so we still have access to the original instructors array. We can use this method to replace Array.pop(), and Array.unshift().

The point to remember is that the spread operator creates a brand new array and takes all the value of the original array and spread it into the new array.

Using items of a array in a function

let's consider how we can use individual items of an array as parameter in a function. I want to log into the console a string: "I started learning TypeScript in the 2021. expertise level: Intermediate.

In the first approach we use the regular method of solving this. Then in the second approach we'd use the spread operator.

First Approach:

function myTechStack(language, year, level) {
    return `I started learning ${language} in ${year} . expertise level:  ${level}`;
}

let language = ["TypeScript", 2021, "intermediate"];

let news = myTechStack.apply(null, language);

Second Approach:

function myTechStack(lTanguage, year, level) {
    return `I started learning ${language} in ${year}. expertise level:  ${level}`;
}

let language = ["TypeScript", 2021, "intermediate"];

let news = myTechStack( …language);

The first approach and second approach work the same. The cool thing about the spread operator in this case is that it makes the code readable and easy to understand. To understand how the first approach works one would need to understand how the apply, bind and call syntax works. But in the second approach we just spread all the items in the language array into a string and number, and each item is used in the function. Pretty straight forward right!

The spread operator is indeed powerful and it's aids code readability and with it we can avoid data mutation. We've barely stretch the surface of the the cool stuff we can achieve with the spread operator. The code samples are basic but beginner friendly. Although we only consider examples with array but the same idea can be applied when dealing with objects and Maps. You can get your hands dirty, I guess it would help you learn faster.

That's All for now! Pretty basic but powerful 😃🐱‍👤 Remember, Your health is Your wealth!