> Что такое иммутабельность в JavaScript (JavaScript)

Уровень: junior · Роль: frontend · Категория: Технические вопросы

Компании: IT-One

Стек: JavaScript

> Пример ответа

Короткий ответ

Иммутабельность - это принцип, при котором данные не изменяются после создания. Вместо изменения существующего объекта или массива создаётся новая копия с нужными изменениями. В JavaScript примитивы (строки, числа) иммутабельны по умолчанию, а объекты и массивы - мутабельны. Для соблюдения иммутабельности используют методы без побочных эффектов, например map, filter, reduce, или библиотеки вроде Immer.

Подробное объяснение

Иммутабельность означает, что значение переменной не может быть изменено после его создания. Если нужно изменить данные, создаётся новый объект с применёнными изменениями, а старый остаётся нетронутым. В JavaScript примитивные типы (number, string, boolean, null, undefined, symbol, bigint) иммутабельны - любая операция над ними возвращает новое значение. Объекты и массивы мутабельны: их свойства можно менять напрямую.

Иммутабельность важна для:

  • Предсказуемости кода - функция, работающая с иммутабельными данными, не имеет побочных эффектов.
  • Упрощения отладки - состояние не меняется неожиданно.
  • Оптимизации производительности в React и Redux - компоненты перерисовываются только при изменении ссылки на объект.
  • Безопасности в многопоточных средах (хотя JS однопоточный, иммутабельность полезна в асинхронном коде).

Основные техники:

  • Spread operator: const newObj = { ...oldObj, key: newValue }
  • Object.assign: const newObj = Object.assign({}, oldObj, { key: newValue })
  • Методы массивов без мутации: map, filter, slice, concat, reduce
  • Object.freeze для поверхностной защиты от изменений

На практике

В реальной разработке иммутабельность чаще всего применяется:

  • В React - состояние (state) обновляется через setState или useState, создавая новый объект.
  • В Redux - редьюсеры обязаны возвращать новый объект состояния, не мутируя предыдущее.
  • При работе с массивами - вместо push используют concat или spread, вместо splice - filter или slice.
  • Для глубокого копирования вложенных структур - JSON.parse(JSON.stringify(obj)) (с ограничениями) или библиотеки типа lodash.cloneDeep.

Важно помнить, что spread и Object.assign делают только поверхностное копирование. Для вложенных объектов нужно копировать каждый уровень вручную или использовать библиотеки.

Пример кода

JAVASCRIPT
// Мутация (плохо)
const user = { name: 'Alice', age: 25 };
user.age = 26; // меняем исходный объект
// Иммутабельно (хорошо)
const updatedUser = { ...user, age: 26 };
console.log(user); // { name: 'Alice', age: 25 } - исходный не изменился
// Массивы
const numbers = [1, 2, 3];
const newNumbers = [...numbers, 4]; // вместо numbers.push(4)
const filtered = numbers.filter(n => n > 1); // вместо splice
// В React
const [items, setItems] = useState([1, 2, 3]);
setItems(prev => [...prev, 4]); // создаём новый массив
// В Redux
const reducer = (state, action) => {
return { ...state, value: action.payload }; // новый объект
};

Как отвечать на собеседовании

Начни с чёткого определения: иммутабельность - это неизменяемость данных после создания. Приведи различие между примитивами (иммутабельны) и объектами (мутабельны). Объясни, зачем это нужно: предсказуемость, отладка, работа с React/Redux. Покажи пример кода с мутацией и иммутабельным подходом. Упомяни, что spread делает поверхностное копирование, и для глубоких структур нужны дополнительные инструменты. Если спросят про производительность, скажи, что иммутабельность может быть дороже по памяти, но даёт преимущества в управлении состоянием.

Что проверяет интервьюер

  • Понимание разницы между примитивами и объектами в JS.
  • Знание методов работы с данными без мутации (spread, map, filter, reduce).
  • Осознание практической пользы иммутабельности в современных фреймворках.
  • Умение объяснить, почему мутация может привести к багам.
  • Понимание ограничений поверхностного копирования.

Типичные ошибки

  • Путать иммутабельность с неизменяемостью переменной через const (const запрещает переприсваивание, но не защищает содержимое объекта).
  • Использовать Object.assign или spread для глубокого копирования, не зная про поверхностность.
  • Мутировать состояние в React или Redux напрямую (например, state.items.push(newItem)).
  • Считать, что иммутабельность всегда лучше - в простых скриптах мутация может быть оправдана.
  • Забывать, что методы sort и splice мутируют исходный массив, и не делать копию перед их вызовом.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью