Guidelines
Data Structures

Data Structures

Prefer simple, flat data structures

Using simple, flat data structures allows for easier manipulation and maintenance of the data. They are also more efficient to work with as they require less processing power and memory. In contrast, nested, complex data structures can be more difficult to work with and can lead to performance issues. It is generally better to use simple, flat data structures whenever possible.

Use the right data structure

Using the appropriate data structure can greatly improve the efficiency and performance of your code. Using the wrong data structure can lead to unnecessary complexity and inefficiencies in your code.

Use Array to store collections of items that need to be iterated over or accessed by index.

const months = [
  "January",
  "February",
  "March",
  "April",
  "May",
  "June",
  "July",
  "August",
  "September",
  "October",
  "November",
  "December",
];
 
// Iterate over the months array
months.forEach((month) => console.log(month));
 
// Access an item in the array by index
console.log(months[0]); // Output: "January"

Avoid using classes as a data structure

Classes should be used to define object-oriented code, and should not be used as a simple data structure. Using classes as a data structure can lead to unnecessary complexity and can make the code harder to understand and maintain.

Instead of using classes as a data structure, it is usually better to use plain JavaScript objects or other data structures that are more suited for storing and manipulating data.

const createPerson = (data) => {
  const defaultPerson = { name: "", age: 0 };
  // "person" is a private member that can only be accessed
  // and modified through the methods that have been returned.
  const person = { ...defaultPerson, ...data };
 
  const getName = () => person.name;
  const setName = (value) => (person.name = value);
  const getAge = () => person.age;
  const setAge = (value) => (person.age = value);
 
  return { getName, setName, getAge, setAge };
};
 
const person = createPerson({ name: "John", age: 30 });
person.getName(); // John
person.setName("Jane");
person.getName(); // Jane

Use immutable data structures

An immutable data structure is a data structure that cannot be modified (mutated) once it has been created. This means that any operation that would normally modify the data structure, such as adding or removing an element, will instead create a new data structure with the desired changes.

When using data structures in JavaScript, there are several ways to avoid mutations. Here are a few tactics you could use:

  • Use the spread operator to create shallow copies of objects or arrays. This allows you to work with a copy of the data rather than the original, which can help to prevent mutations.

    const originalArray = [1, 2, 3];
    const copyArray = [...originalArray];
     
    copyArray[0] = 10; // does not modify originalArray
     
    console.log(originalArray); // [1, 2, 3]
    console.log(copyArray); // [10, 2, 3]
  • Use the Object.freeze method to prevent an object from being modified. This can be useful when you want to ensure that an object remains immutable, even if it is passed as an argument to a function.

    const originalObject = { a: 1, b: 2 };
    const frozenObject = Object.freeze(originalObject);
     
    frozenObject.a = 10; // does not modify originalObject
     
    console.log(originalObject); // { a: 1, b: 2 }
    console.log(frozenObject); // { a: 1, b: 2 }
  • Use immutable array methods, such as map, filter, and reduce, to transform data in a way that does not mutate the original data. This can help to reduce the risk of mutations, and can make your code easier to understand and maintain.

    const originalArray = [1, 2, 3];
    const transformedArray = originalArray.map((x) => x * 2);
     
    console.log(originalArray); // [1, 2, 3]
    console.log(transformedArray); // [2, 4, 6]
  • Avoid using global state in your code. Global state can be easily modified by any function in your code, which can lead to mutations and side effects. Instead, consider passing any data that is needed by a function as an argument, or use a immutable state management library to manage your application's state.

    const updateData = ({ data = {}, updates = {} } = {}) => ({
      ...data,
      ...updates,
    });
     
    const data = { name: "Jane", age: 25 };
    const updatedData = updateData({ data, updates: { name: "John" } }); // { name: 'John', age: 25 }
    console.log(data); // { name: 'Jane', age: 25 }
  • Use a library that provides immutable data structures such as Immutable.js (opens in a new tab), Immer (opens in a new tab) or seamless-immutable (opens in a new tab). These libraries provide a wide range of immutable data structures and methods for working with them.

These techniques will help you write more predictable, stable, and dependable code while avoiding mutations and other common sources of bugs and errors.

Last updated on