HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Состоянием называют практически любые временные данные, которые хранятся в памяти, те же переменные либо поля внутри объектов.<strong>Изменчивое состояние</strong>- один из источников сложности ПО, особенно в сочетании с объектной ориентацией. Но почему изменчивое состояние является такой большой проблемой?</p>
1 <p>Состоянием называют практически любые временные данные, которые хранятся в памяти, те же переменные либо поля внутри объектов.<strong>Изменчивое состояние</strong>- один из источников сложности ПО, особенно в сочетании с объектной ориентацией. Но почему изменчивое состояние является такой большой проблемой?</p>
2 <h2>Ограничения человеческого мозга</h2>
2 <h2>Ограничения человеческого мозга</h2>
3 <p>К сожалению, человеческий мозг довольно плохо работает с состоянием, ведь мы способны одновременно хранить в рабочей памяти лишь около 5 элементов. Программирование с изменяемым состоянием можно сравнить с умственным жонглированием. И если жонглировать 2-мя шарами относительно просто, то 3-мя и более - намного тяжелее. То же самое и с написанием кода. Ваш код станет надёжнее, а вы сами станете работать более продуктивно, если отбросите изменчивое состояние.</p>
3 <p>К сожалению, человеческий мозг довольно плохо работает с состоянием, ведь мы способны одновременно хранить в рабочей памяти лишь около 5 элементов. Программирование с изменяемым состоянием можно сравнить с умственным жонглированием. И если жонглировать 2-мя шарами относительно просто, то 3-мя и более - намного тяжелее. То же самое и с написанием кода. Ваш код станет надёжнее, а вы сами станете работать более продуктивно, если отбросите изменчивое состояние.</p>
4 <h2>О реальных проблемах с изменчивым состоянием</h2>
4 <h2>О реальных проблемах с изменчивым состоянием</h2>
5 <p>Давайте глянем, как именно изменчивость способна сделать ваш код более проблематичным:</p>
5 <p>Давайте глянем, как именно изменчивость способна сделать ваш код более проблематичным:</p>
6 const increasePrice = (item, increaseBy) =&gt; { // Так не делайте никогда 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);<p>Как видите, ошибка очень тонка. Меняя аргументы функции, вы ненароком поменяли стоимость исходного элемента. Если предполагалось, что значение равняется десяти, на деле оно поменялось на 13.</p>
6 const increasePrice = (item, increaseBy) =&gt; { // Так не делайте никогда 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);<p>Как видите, ошибка очень тонка. Меняя аргументы функции, вы ненароком поменяли стоимость исходного элемента. Если предполагалось, что значение равняется десяти, на деле оно поменялось на 13.</p>
7 <p>Избежать этого можно, если создавать и возвращать новый объект (неизменность):</p>
7 <p>Избежать этого можно, если создавать и возвращать новый объект (неизменность):</p>
8 const increasePrice = (item, increaseBy) =&gt; ({ ...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);<p>Также учтите, что копирование посредством ES6-оператора "spread" выполнит не глубокую, а поверхностную копию, в результате чего не скопируется ни одно из вложенных свойств. То есть если у товара есть что-то типа item.seller.id, то seller нового товара всё так же будет ссылаться на старый товар.</p>
8 const increasePrice = (item, increaseBy) =&gt; ({ ...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);<p>Также учтите, что копирование посредством ES6-оператора "spread" выполнит не глубокую, а поверхностную копию, в результате чего не скопируется ни одно из вложенных свойств. То есть если у товара есть что-то типа item.seller.id, то seller нового товара всё так же будет ссылаться на старый товар.</p>
9 <p>Осталось посмотреть предлагаемую конфигурацию ESLint:</p>
9 <p>Осталось посмотреть предлагаемую конфигурацию ESLint:</p>
10 rules: fp/no-mutation: warn no-param-reassign: warn<h2>Не применяйте push для массивов</h2>
10 rules: fp/no-mutation: warn no-param-reassign: warn<h2>Не применяйте push для массивов</h2>
11 <p>Аналогичные проблемы присущи и изменениям массива с применением методов типа push:</p>
11 <p>Аналогичные проблемы присущи и изменениям массива с применением методов типа push:</p>
12 const a = ['apple', 'orange']; const b = a; a.push('microsoft') // ['apple', 'orange', 'microsoft'] console.log(a); // ['apple', 'orange', 'microsoft'] // Сюрпрайз! console.log(b);<p>Неожиданно, ведь вы, скорее всего, ожидали, что массив b останется прежним. Данной ошибки можно относительно просто избежать, если вы создадите вместо вызова push новый массив.</p>
12 const a = ['apple', 'orange']; const b = a; a.push('microsoft') // ['apple', 'orange', 'microsoft'] console.log(a); // ['apple', 'orange', 'microsoft'] // Сюрпрайз! console.log(b);<p>Неожиданно, ведь вы, скорее всего, ожидали, что массив b останется прежним. Данной ошибки можно относительно просто избежать, если вы создадите вместо вызова push новый массив.</p>
13 const newArray = [...a, 'microsoft'];<p><em><a>Источник</a></em></p>
13 const newArray = [...a, 'microsoft'];<p><em><a>Источник</a></em></p>
14  
14