The spread and rest operators: more efficient arrays and objects.

So lately i've been using Redux in one of my Angular app. It has been super fun and super useful to say the least. It takes a little adjusting to get used to their state model and one of the adjustments is the usage of pure functions. In the following post i'll illustrate a use case for the spread operator and then show you how to use it.

Pure functions basically say two things: that you cannot modify / mutate the value of parameters passed into the function and that the return value is derived from the parameters passed in. In essence, a pure function should always have a predictable output given the same set of inputs.

With that being said, my first question was, "well, how do you modify an array or object without changing it?", and the answer is to create a new one. Basically, you create a copy of the state you're given and then add on the extra info.

For the purposes of this article we will focus on the theory of the spread operator and not be concerned with creating acutal reducer methods.

The challenge - look but don't touch

Let's say we have a function, addItemToArray. Ingenious name I know! The method function takes an array, and returns a new one without modifying the original array.

function addItemToArray(initialArrayState = [], newValue)  
   let newStateArray = initialArrayState.concat(newValue);

return newStateArray;  

So this approach is not that bad. We aren't mutating the params passed in as we're using concat to return a new array based on the contents of the two arguments. We can do a little better though and make this even shorter and more concise.

Enter the spread operator
function addItemToArray(initialArrayState = [], newValue)  
   return [...initialArrayState, newValue];

Where the spread operator works by "expanding elements" into new ones such as when you have an expression where you want to be able to add more data, like an array, or function arguments, there is another operator that condenses multiple elements into one.

The Rest Operator

The rest operator, or aka the object spread operator let's you concatenate values from other objects onto a different object. Let's do another example.

const INITIAL_STATE = {"foo" : "bar"};  
let newValue = {"pet": "fido"};

function addItemToObj(initialObjState = INITIAL_STATE, newValue)  
   return {...initialObjState, newValue};

The result of this is a new composed object based on the arguments passed to our function. You can think of this as being similar to jQuery's extend or ES2015's Object.assign.


This is just the tip of the iceberg. There is a lot more than you can do with the spread and rest operators. Check out these links below to find out more.