Изменчивое состояние в JavaScript | OTUS
🔥 Успейте получить скидку!
Только до 27.01 можно приобрести курсы со скидкой 25%. Торопитесь!
Выбрать курс

Курсы

Программирование
Разработчик программных роботов (RPA) на базе UiPath и PIX
-25%
Разработчик C#
-25%
Алгоритмы и структуры данных
-25%
Backend-разработчик на PHP
-25%
JavaScript Developer. Professional
-25%
Team Lead
-25%
Golang Developer. Professional
-25%
Agile Project Manager
-25%
Flutter Mobile Developer
-25%
Android Developer. Professional
-11%
MS SQL Server Developer
-8%
C++ Developer. Professional Framework Laravel Cloud Solution Architecture Highload Architect Reverse-Engineering. Professional Kotlin Backend Developer React.js Developer VOIP инженер Нереляционные базы данных Scala-разработчик Супер-практикум по использованию и настройке GIT IoT-разработчик JavaScript Developer. Basic Advanced Fullstack JavaScript developer Unity Game Developer. Professional Супер-интенсив Azure
Инфраструктура
Супер-интенсив "Версионирование и командная работа с помощью Git"
-30%
Administrator Linux. Professional
-25%
Супер-интенсив «CI/CD или Непрерывная поставка с Docker и Kubernetes»
-30%
Разработчик программных роботов (RPA) на базе UiPath и PIX
-25%
Administrator Linux. Advanced
-25%
Infrastructure as a code in Ansible
-25%
Network engineer
-25%
MS SQL Server Developer
-8%
Cloud Solution Architecture Highload Architect Разработчик голосовых ассистентов и чат-ботов Мониторинг и логирование: Zabbix, Prometheus, ELK Супер-практикум по работе с протоколом BGP Супер - интенсив по паттернам проектирования Супер - интенсив по Kubernetes Архитектор сетей Супер-интенсив «IaC Ansible»
Специализации Курсы в разработке Подготовительные курсы
+7 499 938-92-02

Изменчивое состояние в JavaScript

Состоянием называют практически любые временные данные, которые хранятся в памяти, те же переменные либо поля внутри объектов. Изменчивое состояние — один из источников сложности ПО, особенно в сочетании с объектной ориентацией. Но почему изменчивое состояние является такой большой проблемой?

Ограничения человеческого мозга

К сожалению, человеческий мозг довольно плохо работает с состоянием, ведь мы способны одновременно хранить в рабочей памяти лишь около 5 элементов. Программирование с изменяемым состоянием можно сравнить с умственным жонглированием. И если жонглировать 2-мя шарами относительно просто, то 3-мя и более — намного тяжелее. То же самое и с написанием кода. Ваш код станет надёжнее, а вы сами станете работать более продуктивно, если отбросите изменчивое состояние.

О реальных проблемах с изменчивым состоянием

Давайте глянем, как именно изменчивость способна сделать ваш код более проблематичным:

const increasePrice = (item, increaseBy) => {
  // Так не делайте никогда
  item.price += increaseBy;

  return item;
};

const oldItem = { price: 10 };

const newItem = increasePrice(oldItem, 3);

// Выводится «newItem.price 13»
console.log('newItem.price', newItem.price);

// Выводится «oldItem.price 13»
// Сюрпрайз!
console.log('oldItem.price', oldItem.price);

Как видите, ошибка очень тонка. Меняя аргументы функции, вы ненароком поменяли стоимость исходного элемента. Если предполагалось, что значение равняется десяти, на деле оно поменялось на 13.

Избежать этого можно, если создавать и возвращать новый объект (неизменность):

const increasePrice = (item, increaseBy) => ({
  ...item,
  price: item.price + increaseBy
});

const oldItem = { price: 10 };

const newItem = increasePrice(oldItem, 3);

// Выводится «newItem.price 13»
console.log('newItem.price', newItem.price);

// Выводится «oldItem.price 10»
// Как и ожидали
console.log('oldItem.price', oldItem.price);

Также учтите, что копирование посредством ES6-оператора «spread» выполнит не глубокую, а поверхностную копию, в результате чего не скопируется ни одно из вложенных свойств. То есть если у товара есть что-то типа item.seller.id, то seller нового товара всё так же будет ссылаться на старый товар.

Осталось посмотреть предлагаемую конфигурацию ESLint:

rules:
  fp/no-mutation: warn
  no-param-reassign: warn

Не применяйте push для массивов

Аналогичные проблемы присущи и изменениям массива с применением методов типа push:

const a = ['apple', 'orange'];
const b = a;

a.push('microsoft')

// ['apple', 'orange', 'microsoft']
console.log(a);

// ['apple', 'orange', 'microsoft']
// Сюрпрайз!
console.log(b);

Неожиданно, ведь вы, скорее всего, ожидали, что массив b останется прежним. Данной ошибки можно относительно просто избежать, если вы создадите вместо вызова push новый массив.

const newArray = [...a, 'microsoft'];

Источник

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Только до 27 января!
🔥 СКИДКА 25% на курсы OTUS!