0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>В этом уроке мы рассмотрим другую сторону операции rest - операцию spread. Мы узнаем, как выглядит базовое использование этой операции, как она позволяет работать в неизменяемом виде с формированием новых структур данных и как ее можно использовать в функциях высшего порядка.</p>
1
<p>В этом уроке мы рассмотрим другую сторону операции rest - операцию spread. Мы узнаем, как выглядит базовое использование этой операции, как она позволяет работать в неизменяемом виде с формированием новых структур данных и как ее можно использовать в функциях высшего порядка.</p>
2
<h2>Базовое использование spread</h2>
2
<h2>Базовое использование spread</h2>
3
<p>spread переводится как растягивание. Она берет коллекцию и растягивает ее на отдельные элементы. Посмотрим ее базовое использование.</p>
3
<p>spread переводится как растягивание. Она берет коллекцию и растягивает ее на отдельные элементы. Посмотрим ее базовое использование.</p>
4
<p>Мы можем задать список таким образом:</p>
4
<p>Мы можем задать список таким образом:</p>
5
<p>Здесь мы перечисляем все аргументы через запятую и на выходе получаем некоторую коллекцию. А можем сделать и по-другому:</p>
5
<p>Здесь мы перечисляем все аргументы через запятую и на выходе получаем некоторую коллекцию. А можем сделать и по-другому:</p>
6
<p>Здесь мы передаем массив, но слева поставили три точки. Вызов будет преобразован в l( , 10, 23, 234).</p>
6
<p>Здесь мы передаем массив, но слева поставили три точки. Вызов будет преобразован в l( , 10, 23, 234).</p>
7
<p>В этом случае мы видим похожий подход, но это не rest, а именно spread. Используются так же три точки, но в зависимости от места применения это либо rest, либо spread. В данном случае операция применяется к коллекциям, поэтому это spread.</p>
7
<p>В этом случае мы видим похожий подход, но это не rest, а именно spread. Используются так же три точки, но в зависимости от места применения это либо rest, либо spread. В данном случае операция применяется к коллекциям, поэтому это spread.</p>
8
<p>Общая форма выглядит так:</p>
8
<p>Общая форма выглядит так:</p>
9
<p>Здесь мы вызываем функцию и передаем туда некий iterable object, например, массив.</p>
9
<p>Здесь мы вызываем функцию и передаем туда некий iterable object, например, массив.</p>
10
<p>В итоге ставим три точки в начале, и это означает, что это spread, который будет растягивать коллекцию на элементы и вызывать функцию соответствующим количеством аргументов.</p>
10
<p>В итоге ставим три точки в начале, и это означает, что это spread, который будет растягивать коллекцию на элементы и вызывать функцию соответствующим количеством аргументов.</p>
11
<p>При этом spread в отличие от rest используется шире и не только в вызове функций.</p>
11
<p>При этом spread в отличие от rest используется шире и не только в вызове функций.</p>
12
<h2>Аргументы</h2>
12
<h2>Аргументы</h2>
13
<p>Рассмотрим, как spread может использоваться в вызове функций в более расширенном примере.</p>
13
<p>Рассмотрим, как spread может использоваться в вызове функций в более расширенном примере.</p>
14
<p>Поскольку rest используется только в конце, с ним всё гораздо проще. А spread может использоваться в любом месте. Рассмотрим на примере.</p>
14
<p>Поскольку rest используется только в конце, с ним всё гораздо проще. А spread может использоваться в любом месте. Рассмотрим на примере.</p>
15
<p>Допустим, у нас есть функция, которая ожидает на вход пять параметров:</p>
15
<p>Допустим, у нас есть функция, которая ожидает на вход пять параметров:</p>
16
<p>Мы передаем ей первый параметр, потом args - этот массив растягивается. Причем args состоит из двух элементов.</p>
16
<p>Мы передаем ей первый параметр, потом args - этот массив растягивается. Причем args состоит из двух элементов.</p>
17
<p>Далее мы передаем еще один параметр и массив, который состоит из одного параметра и тоже растягивается. В итоге у нас получается, что функция вызывается с пятью параметрами.</p>
17
<p>Далее мы передаем еще один параметр и массив, который состоит из одного параметра и тоже растягивается. В итоге у нас получается, что функция вызывается с пятью параметрами.</p>
18
<p>Неважно, подставляем мы идентификатор или напрямую массив. Принцип одинаковый.</p>
18
<p>Неважно, подставляем мы идентификатор или напрямую массив. Принцип одинаковый.</p>
19
<p>Теперь рассмотрим пример с массивами:</p>
19
<p>Теперь рассмотрим пример с массивами:</p>
20
<p>push принимает любое количество аргументов. Это хороший способ расширить один массив другим. Для этого мы делаем push и растягиваем второй массив внутри метода. Если мы распечатаем первый массив, то получим один плоский массив:</p>
20
<p>push принимает любое количество аргументов. Это хороший способ расширить один массив другим. Для этого мы делаем push и растягиваем второй массив внутри метода. Если мы распечатаем первый массив, то получим один плоский массив:</p>
21
<p>Здесь происходит не присоединение последним элементом массива arr2, а каждый элемент из arr2 записывается как отдельный параметр через запятую:</p>
21
<p>Здесь происходит не присоединение последним элементом массива arr2, а каждый элемент из arr2 записывается как отдельный параметр через запятую:</p>
22
<h2>Immutable way</h2>
22
<h2>Immutable way</h2>
23
<p>Также spread позволяет работать в неизменяемом виде с формированием новых структур данных. То есть вместо того, чтобы использовать push и изменять объект, мы можем расширить массив - фактически создать новый без изменения старого:</p>
23
<p>Также spread позволяет работать в неизменяемом виде с формированием новых структур данных. То есть вместо того, чтобы использовать push и изменять объект, мы можем расширить массив - фактически создать новый без изменения старого:</p>
24
<p>Здесь мы создаем массив и внутри него используем тот же spread. В итоге iterableObj будет преобразован в элементы этого массива.</p>
24
<p>Здесь мы создаем массив и внутри него используем тот же spread. В итоге iterableObj будет преобразован в элементы этого массива.</p>
25
<p>spread можно поставить в любом месте. И полученное выражение вернет нам новую структуру данных - новый массив без изменения старого.</p>
25
<p>spread можно поставить в любом месте. И полученное выражение вернет нам новую структуру данных - новый массив без изменения старого.</p>
26
<p>То же работает и со строчками:</p>
26
<p>То же работает и со строчками:</p>
27
<h2>Immutable Reduce</h2>
27
<h2>Immutable Reduce</h2>
28
<p>Теперь рассмотрим, как это можно использовать в функциях высшего порядка.</p>
28
<p>Теперь рассмотрим, как это можно использовать в функциях высшего порядка.</p>
29
<p>Например, мы можем написать функцию reverse таким образом:</p>
29
<p>Например, мы можем написать функцию reverse таким образом:</p>
30
<p>Здесь мы используем reduce, внутри которого разворачиваем аккумулятор. И мы формируем каждый раз новый массив - добавляем новое значение слева от значений в acc. В итоге мы получаем массив, в котором все элементы в обратном порядке.</p>
30
<p>Здесь мы используем reduce, внутри которого разворачиваем аккумулятор. И мы формируем каждый раз новый массив - добавляем новое значение слева от значений в acc. В итоге мы получаем массив, в котором все элементы в обратном порядке.</p>
31
<p>При таком подходе каждый раз происходит копирование. В определенных языках это хорошо оптимизировано. Но в JavaScript этот процесс занимает время. Если замерить производительность этого кода с копированием, а не с использованием push, он будет достаточно медленным. Поэтому на больших объемах стоит использовать более оптимизированные варианты.</p>
31
<p>При таком подходе каждый раз происходит копирование. В определенных языках это хорошо оптимизировано. Но в JavaScript этот процесс занимает время. Если замерить производительность этого кода с копированием, а не с использованием push, он будет достаточно медленным. Поэтому на больших объемах стоит использовать более оптимизированные варианты.</p>
32
<p>Если выводить на страницу до ста элементов, это не повлияет на производительность. При этом можно использовать уже готовые функции. Например, фреймворк React или Redux, которые предлагают управлять стейтом в неизменяемом виде.</p>
32
<p>Если выводить на страницу до ста элементов, это не повлияет на производительность. При этом можно использовать уже готовые функции. Например, фреймворк React или Redux, которые предлагают управлять стейтом в неизменяемом виде.</p>
33
<p>Рассмотрим еще один пример с дублированием:</p>
33
<p>Рассмотрим еще один пример с дублированием:</p>
34
<p>Здесь фактически происходит то же самое. При этом задача в том, чтобы продублировать каждый элемент. В итоге мы формируем новый массив, делаем spread и в конце записываем value, value. И на выходе получается массив, в котором каждый элемент продублирован два раза.</p>
34
<p>Здесь фактически происходит то же самое. При этом задача в том, чтобы продублировать каждый элемент. В итоге мы формируем новый массив, делаем spread и в конце записываем value, value. И на выходе получается массив, в котором каждый элемент продублирован два раза.</p>
35
<h2>Объекты</h2>
35
<h2>Объекты</h2>
36
<p>Spread операцию можно применять не только к массивам, но и к объектам:</p>
36
<p>Spread операцию можно применять не только к массивам, но и к объектам:</p>
37
<p>Такой способ позволяет работать с объектами в неизменяемом стиле, что часто используется в коде, например, во фронтенде:<a>https://redux.js.org/recipes/using-object-spread-operator</a></p>
37
<p>Такой способ позволяет работать с объектами в неизменяемом стиле, что часто используется в коде, например, во фронтенде:<a>https://redux.js.org/recipes/using-object-spread-operator</a></p>
38
<p>Если во время применения растягивания повторяются ключи, то в результирующий объект записывается правое значение:</p>
38
<p>Если во время применения растягивания повторяются ключи, то в результирующий объект записывается правое значение:</p>
39
<p>Эту операцию можно использовать много раз подряд. Например, так можно сливать два объекта в один:</p>
39
<p>Эту операцию можно использовать много раз подряд. Например, так можно сливать два объекта в один:</p>
40
<h2>Выводы</h2>
40
<h2>Выводы</h2>
41
<p>В этом уроке мы рассмотрели другую сторону операции rest - операцию spread. Мы узнали, как выглядит базовое использование этой операции, как она позволяет работать в неизменяемом виде с формированием новых структур данных и как ее можно использовать в функциях высшего порядка.</p>
41
<p>В этом уроке мы рассмотрели другую сторону операции rest - операцию spread. Мы узнали, как выглядит базовое использование этой операции, как она позволяет работать в неизменяемом виде с формированием новых структур данных и как ее можно использовать в функциях высшего порядка.</p>