> Какие данные можно мутировать в JavaScript, а какие нет (JavaScript)

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

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

Стек: JavaScript

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

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

В JavaScript мутировать можно объекты, массивы, функции, классы, Map, Set и другие ссылочные типы - их содержимое изменяется по ссылке. Нельзя мутировать примитивы: number, string, boolean, null, undefined, symbol, bigint - они иммутабельны по своей природе. Любая операция над примитивом возвращает новое значение, не изменяя исходное. Также нельзя напрямую мутировать замороженные объекты через Object.freeze() - попытка изменения либо игнорируется, либо выбрасывает ошибку в strict mode.

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

Ключевое различие - ссылочный тип против примитивного. Примитивы хранятся по значению, и все операции с ними создают новое значение. Например, let a = "hello"; a.toUpperCase() вернёт новую строку, но a останется "hello". То же с числами: let n = 5; n + 1 не меняет n.

Ссылочные типы (объекты, массивы, функции) хранятся по ссылке. Мутация - это изменение внутреннего состояния без изменения ссылки. Примеры мутаций:

  • obj.key = value
  • arr.push(item)
  • obj.method() если метод меняет состояние
  • map.set(key, value)

Важно: const не запрещает мутацию - он запрещает переприсваивание ссылки. const obj = {}; obj.a = 1 - валидно, а obj = {} - ошибка.

Иммутабельность примитивов - это не ограничение языка, а их фундаментальное свойство. Даже Object.freeze() работает только на верхнем уровне - вложенные объекты остаются мутабельными, если не заморозить их рекурсивно.

На практике

В реальной фронтенд-разработке это важно для:

  • state management (Redux, Zustand) - требует иммутабельных обновлений
  • React - сравнение пропсов и состояния по ссылке
  • отладки - мутации могут вызывать неожиданные побочные эффекты, особенно при передаче объектов в функции

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

JAVASCRIPT
// мутация
const user = { name: 'John' };
user.name = 'Jane';
// иммутабельно
const updatedUser = { ...user, name: 'Jane' };

Для массивов: arr.push() - мутация, [...arr, item] - иммутабельно.

Пример кода

JAVASCRIPT
// Примитивы - иммутабельны
let str = 'hello';
str[0] = 'H'; // не работает, строка не меняется
console.log(str); // 'hello'
let num = 42;
num.foo = 'bar'; // в non-strict mode молча игнорируется
console.log(num.foo); // undefined
// Ссылочные типы - мутабельны
const obj = { count: 0 };
obj.count++; // мутация
console.log(obj.count); // 1
const arr = [1, 2, 3];
arr.push(4); // мутация
console.log(arr); // [1, 2, 3, 4]
// Object.freeze - поверхностная заморозка
const frozen = Object.freeze({ nested: { value: 1 } });
frozen.nested.value = 2; // работает, вложенный объект не заморожен
console.log(frozen.nested.value); // 2

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

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

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

Интервьюер проверяет:

  • понимание фундаментального различия между примитивами и ссылочными типами
  • знание, что const не делает объекты иммутабельными
  • осознание практических последствий мутаций в реальном коде
  • умение объяснить, почему строки и числа нельзя изменить
  • знание методов заморозки и их ограничений

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

  • утверждение, что const запрещает мутацию объектов
  • попытка мутировать строку через индекс - str[0] = 'x' и ожидание изменения
  • игнорирование того, что Object.freeze() работает только поверхностно
  • смешивание понятий "переприсваивание" и "мутация"
  • утверждение, что все объекты можно мутировать - забывают про Object.freeze() и Object.seal()
  • непонимание, что методы вроде Array.prototype.sort() и splice() мутируют массив, а map() и filter() - нет

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

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