Skip to main content Accessibility Feedback

Immutable arrays and objects in vanilla JS

Today, we’re going to talk about immutability in JavaScript. Let’s dig in.

What is immutability?

In JavaScript, things that are immutable don’t change in value when you use them, and things that are mutable do.

For example, lets create a variable, age1, and assign its value to another variable, age2. If we update age2, the original variable, age1, is unaffected.

// Create a variable
let age1 = 42;

// Assign it to a new variable
let age2 = age1;

// Update the new variable
age2 = 84;

// logs 42
console.log(age1);

Here’s a demo.

In JavaScript, when you assign an existing array or object to a new variable, it does not create a new array or object with the same properties. Instead, it creates a reference to the original.

It is not immutable.

// Original array and object
let sandwiches = ['turkey', 'tuna', 'ham', 'pb&j'];
let lunch = {
	sandwich: 'turkey',
	chips: 'cape cod',
	drink: 'soda'
};

// These create references to the original
let moreSandwiches = sandwiches;
let moreLunch = lunch;

// Remove "tuna" from sandwiches
// Remove "chips" from lunch
sandwiches.splice(1, 1);
delete lunch.chips;

// logs ["turkey", "ham", "pb&j"]
console.log(moreSandwiches);

// Logs {sandwich: "turkey", drink: "soda"}
console.log(moreLunch);

Here’s another demo.

Strings and numbers are naturally immutable, but arrays and objects are not.

How to create an immutable array

You can create an immutable copy of an array using Array.slice() with no arguments, or with the Array.from() method. It’s considered a best practice to do so before manipulating an array.

// Create an immutable copy
let evenMoreSandwiches = Array.from(sandwiches);

// Add a few sandwiches
sandwiches.push('italian', 'blt');

// logs ["turkey", "ham", "pb&j", "italian", "blt"]
console.log(sandwiches);

// logs ["turkey", "ham", "pb&j"]
console.log(evenMoreSandwiches);

Here’s a demo of how to create an immutable array.

How to create an immutable object

You can create an immutable copy of an object using Object.assign(). Pass in an empty object ({}) as the first argument and the object you want to copy as the second.

It’s considered a best practice to do so before manipulating an object.

// Create an immutable copy
let evenMoreLunch = Object.assign({}, lunch);

// Add a snack
lunch.snack = 'cookies';

// Logs {sandwich: 'turkey', drink: soda, snack: 'cookies'}
console.log(lunch);

// Logs {sandwich: 'turkey', drink: soda}
console.log(evenMoreLunch);

Here’s a demo of how to create an immutable object.

You can use the spread operator for this, too

Last month, we learned about the spread syntax operator. You can use the spread operator to create immutable copies of arrays and objects instead of use Array.from() or Object.assign().

let moreSandwiches = [...sandwiches];
let moreLunch = {...lunch};

Here’s a demo with an array, and here’s one with an object.

I personally prefer the more verbose Array.from() and Object.assign(), but many folks like the spread operator for it’s brevity. I suspect I will in time as well.

Tomorrow, we’ll look at immutability in nested or multidimensional arrays and objects.