Hack Frontend Community

Иммутабельность и мутабельность в JavaScript

В JavaScript данные можно изменять двумя способами: мутабельно и иммутабельно. Понимание разницы между ними особенно важно при работе с состоянием (state) в React, Redux и других библиотеках.


Мутабельность (mutability)

Мутабельность означает, что объект может быть изменён после создания.

const user = { name: "Alice" };
user.name = "Bob"; // изменяем напрямую
console.log(user); // { name: "Bob" }

Такие изменения происходят по ссылке, и могут вызывать непредсказуемое поведение, особенно если один и тот же объект используется в нескольких места

Иммутабельность (immutability)

Иммутабельность означает, что объект не изменяется, а при изменениях создаётся новая копия.

const user = { name: "Alice" };
const updatedUser = { ...user, name: "Bob" }; // создаём новый объект

console.log(user);        // { name: "Alice" }
console.log(updatedUser); // { name: "Bob" }

Иммутабельность делает данные предсказуемыми и безопасными для сравнения, что критично при ререндеринге компонентов в React.

Иммутабельность в React

React не отслеживает изменения по содержимому объектов, он сравнивает их по ссылке (===).

Поэтому мутабельное обновление не вызовет ререндер:

// неправильный подход
state.items.push("newItem");
setState(state); // ссылка та же → React не обновит компонент

Правильный иммутабельный способ:

// создаём новый массив
setState({ ...state, items: [...state.items, "newItem"] });

Сравнение

СвойствоМутабельностьИммутабельность
Изменение данныхВносится прямо в объектСоздаётся новая копия
Поведение в ReactМожет не вызвать ререндерВсегда надёжно вызывает ререндер
Безопасность данныхВозможны побочные эффектыДанные защищены от мутаций
Удобство отладкиТруднее отслеживатьЛегче отслеживать изменения

Примеры иммутабельных операций:

// массивы
const newArr = [...oldArr, newItem];
const filtered = oldArr.filter(item => item !== target);

// объекты
const newObj = { ...oldObj, updatedKey: newValue };

// вложенные объекты
const updated = {
  ...state,
  user: {
    ...state.user,
    name: "John",
  },
};

Вывод:

Используйте иммутабельность, чтобы сделать код предсказуемым, безопасным и совместимым с React. Это основа корректной работы useEffect, React.memo, Redux и других инструментов.