← Назад к вопросам

В чем разница между модификацией и изменением?

2.2 Middle🔥 161 комментариев
#JavaScript Core#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В чем разница между модификацией и изменением?

В программировании и веб-разработке модификация и изменение — это тесно связанные, но немного разные концепции. Изменение — это общий процесс, а модификация — это специфичный способ изменения, обычно без замены на новый объект.

Изменение (Mutation/Change) — любое преобразование

Изменение — это общий термин для любого преобразования данных, независимо от того, как оно происходит.

// Изменение 1: через модификацию (изменение существующего объекта)
const user = { name: 'John' };
user.name = 'Jane';  // Модифицировали существующий объект

// Изменение 2: через замену (создание нового объекта)
let user = { name: 'John' };
user = { name: 'Jane' };  // Заменили переменную на новый объект

// Оба способа — это "изменение данных"

Модификация (Modification) — изменение существующего объекта

Модификация — это изменение содержимого существующего объекта без создания нового объекта. Это напрямую меняет данные в памяти (mutates state).

// Модификация — меняем существующий объект
const user = { name: 'John', age: 30 };
user.name = 'Jane';      // Модификация свойства
user.age = 31;           // Модификация свойства
console.log(user);       // { name: 'Jane', age: 31 }

// Это ТОТЖЕ объект в памяти, просто его свойства изменились

Практическое различие

// МОДИФИКАЦИЯ (mutation) — меняем существующий объект
const arr = [1, 2, 3];
arr[0] = 10;          // Модифицировали первый элемент
arr.push(4);          // Модифицировали (добавили в конец)
arr.splice(0, 1);     // Модифицировали (удалили первый элемент)

// ИЗМЕНЕНИЕ без модификации — создаём новый объект
const arr = [1, 2, 3];
const newArr = [10, ...arr.slice(1)];  // Новый массив, не модификация
const newArr2 = [...arr, 4];           // Новый массив, не модификация
const newArr3 = arr.filter(x => x !== 1);  // Новый массив, не модификация

Модификация vs Неизменяемость (Immutability)

В современной разработке часто предпочитают неизменяемость вместо модификации:

// Плохо: модификация (mutation)
const state = { user: { name: 'John' } };
state.user.name = 'Jane';  // Изменили исходный объект

// Хорошо: неизменяемость (immutability)
const state = { user: { name: 'John' } };
const newState = {
  ...state,
  user: { ...state.user, name: 'Jane' }  // Новый объект, старый не трогаем
};

React и модификация

В React запрещено модифицировать state напрямую. Это вызывает ошибки и проблемы с рендерингом:

// ❌ ПЛОХО — прямая модификация (mutation)
function UserProfile() {
  const [user, setUser] = useState({ name: 'John' });
  
  const updateName = () => {
    user.name = 'Jane';  // Модифицировали state!
    setUser(user);       // React не заметит изменение!
  };
  
  return <button onClick={updateName}>{user.name}</button>;
}

// ✅ ХОРОШО — создаём новый объект (immutability)
function UserProfile() {
  const [user, setUser] = useState({ name: 'John' });
  
  const updateName = () => {
    setUser({ ...user, name: 'Jane' });  // Новый объект!
  };
  
  return <button onClick={updateName}>{user.name}</button>;
}

Почему это важно:

// React сравнивает объекты по ссылке
const oldState = { name: 'John' };
const newState = oldState;  // Одна и та же ссылка
oldState.name = 'Jane';     // Модифицировали

console.log(oldState === newState);  // true (одна ссылка)
// React не заметит изменение!

// Правильно:
const oldState = { name: 'John' };
const newState = { ...oldState, name: 'Jane' };  // Новая ссылка

console.log(oldState === newState);  // false (разные ссылки)
// React заметит изменение и перерендерит!

Массивы: модификация vs неизменяемость

const items = ['apple', 'banana', 'orange'];

// Методы МАССИВА с МОДИФИКАЦИЕЙ (mutation):
items.push('grape');        // Добавляет в конец
items.pop();                // Удаляет с конца
items.unshift('mango');     // Добавляет в начало
items.shift();              // Удаляет с начала
items.splice(1, 1);         // Удаляет элемент по индексу
items.reverse();            // Реверсит массив
items.sort();               // Сортирует
items[0] = 'pineapple';     // Меняет элемент

// Методы БЕЗ модификации (immutable):
items.concat(['grape']);    // Новый массив
[...items, 'grape'];        // Новый массив
items.filter(x => x !== 'banana');  // Новый массив
items.map(x => x.toUpperCase());    // Новый массив

Объекты: модификация vs неизменяемость

const user = { name: 'John', email: 'john@example.com' };

// МОДИФИКАЦИЯ:
user.name = 'Jane';           // Меняем существующий объект
delete user.email;            // Удаляем из существующего
Object.assign(user, { age: 30 });  // Меняем существующий

// НЕИЗМЕНЯЕМОСТЬ (новые объекты):
const newUser = { ...user, name: 'Jane' };  // Spread
const newUser2 = Object.assign({}, user, { name: 'Jane' });  // Новый объект
const newUser3 = JSON.parse(JSON.stringify(user));  // Глубокая копия

Вложенные объекты

const user = {
  name: 'John',
  address: { city: 'New York', zip: '10001' }
};

// ❌ НЕПРАВИЛЬНО — это модификация!
const newUser = { ...user };
newUser.address.city = 'Boston';  // Меняем вложенный объект
console.log(user.address.city);   // "Boston" (исходный тоже изменился!)

// ✅ ПРАВИЛЬНО — глубокая копия
const newUser = {
  ...user,
  address: { ...user.address, city: 'Boston' }
};
console.log(user.address.city);  // "New York" (исходный не изменился)

Immer для упрощения

Библиотека Immer позволяет писать код с модификацией, но на самом деле создаёт новые объекты:

import { produce } from 'immer';

const user = { name: 'John', age: 30 };

const newUser = produce(user, draft => {
  draft.name = 'Jane';  // Выглядит как модификация
  draft.age = 31;       // Но Immer создаёт новый объект
});

console.log(user === newUser);  // false (разные объекты)

Redux и модификация

Redux запрещает модификацию state по той же причине, что и React:

// ❌ ПЛОХО
const reducer = (state, action) => {
  state.count = state.count + 1;  // Модификация!
  return state;                    // Та же ссылка
};

// ✅ ХОРОШО
const reducer = (state = 0, action) => {
  if (action.type === 'INCREMENT') {
    return state + 1;  // Новое значение
  }
  return state;
};

// Для объектов:
const reducer = (state = {}, action) => {
  if (action.type === 'UPDATE_USER') {
    return { ...state, user: action.payload };  // Новый объект
  }
  return state;
};

Когда модификация оправдана

Модификация приемлема только в этих случаях:

  1. Локальные переменные, которые не используются как state
// OK — это не state
let sum = 0;
sum += 10;  // Модификация OK
sum += 20;
  1. После создания объекта, до использования его как state
const createUser = () => {
  const user = {};  // Новый объект
  user.name = 'John';  // Модификация OK (только что создан)
  user.email = 'john@example.com';
  return user;  // Возвращаем
};

Контрольный список

  • React state — используй spread или новые объекты
  • Redux state — никогда не модифицируй, создавай новые объекты
  • Вложенные объекты — глубокое копирование
  • Массивы — используй методы без модификации (map, filter, concat)
  • Объекты с Array методами — используй spread или Object.assign для новых объектов
  • Immer для упрощения работы с вложенными структурами

Ключевые выводы

  • Изменение — общий процесс преобразования данных
  • Модификация — конкретный способ изменения, меняет существующий объект
  • В React и Redux модификация запрещена, используй неизменяемость (immutability)
  • Spread operator ({...obj}) и методы массивов без модификации — основные инструменты
  • Вложенные структуры требуют глубокого копирования
  • Immer помогает упростить работу с неизменяемостью
В чем разница между модификацией и изменением? | PrepBro