{ Mutation Hazards }

Mutable StructsJavaScript can appear to be deceivingly simple if you’re not watching carefully. It isn’t enforced in most vanilla environments, but we can thank frameworks like React for bringing it to the surface – mutating data structures in JS is usually a really bad idea.

React will not let you mutate an array or object, unless it is done through its state. It’s one of the first things you will really learn when digging into a React project. It’s at the heart of the functional programming paradigm – write as many “pure” functions as you can, which can in theory be re-used throughout your code base and not cause any side effects.

Arrays:

const people = ['Joe', 'Mary', 'Jack', 'George'];

If you wanted to make a copy of it, you could technically write:

const people2 = people;
assert(people === people2, 'Are they the same?'); // true

However, what we’ve done here is made people2reference to people. It’s not a copy, so any changes made down the line to people2 will also be reflected in people and vice versa. These are the side effects that may not be obvious until bugs start popping up all over the place.

The simplest solutions are available in native ES5:

var people2 = people.slice(); // this just "slices" the entire array, making a copy

Or arguably a less efficient way, which creates a new array and concatenates the contents of the old one:

var people2 = [].concat(people);

A more elegant (IMO) ES6 solution with the spread syntax:

const people2 = [...people];

Which is essentially the same as:

const people2 = Array.from(people); // contains optional second callback function argument for mapping

Objects:

For simple shallow cloning of objects (excludes the prototype), Object.assign() has been the standard for awhile.

const people = {
  name: 'Jack Smith',
  height: '6ft',
  weight: 200
};

const people2 = Object.assign({}, people); // assign people object to a new object copy {}

However, there’s now an even shorter away to shallow copy object literals as part of ECMAScript 2018, using the spread syntax as with arrays:

const people2 = { ...people };