Перейти к основному содержимому

Операторы Rest и Spread

@serverSerrverlesskiy

Многие встроенные функции⚙️ JavaScript поддерживают произвольное количество аргументов.

Например:

Math.max(arg1, arg2, ..., argN) – вычисляет максимальное число из переданных аргументов.

Math.min(arg1, arg2, ..., argN) - возвращает минимальное значение из переданных аргументов.

В этой статье мы узнаем, как сделать то же самое с нашими собственными функциями⚙️ и как передавать таким функциям⚙️ параметры в виде массива.

Видео

Остаточные параметры (...rest)

Parametrs

Вызывать функцию⚙️ можно с любым количеством аргументов независимо от того, как она была определена.

Например :

Интерактивный редактор
Результат
Loading...

Лишние аргументы не вызовут ошибку, но конечно посчитаются только первые три.

Концепция ES6

Idea

Начиная со стандарта ES6 появилась концепция, как ...rest - остаточные параметры.

let goFun = (...rest) => {
// Алгоритм
}

Свободные параметры могут быть обозначены через три точки .... Буквально это значит: "собери оставшиеся параметры и положи их в массив".

Например, соберём все аргументы в массив args :

Интерактивный редактор
Результат
Loading...

Ответ уже 28 и без ошибок! Подробуйте изменить аргументы или размерность массива.

Несколько параметров

Мы можем положить первые несколько параметров в переменные , а остальные – собрать в массив. Это означает то, что вы просто можете вставить ...rest, но только вместо последнего параметра функции.

paste

let goFun = (first, second, ...rest) => {
// Алгоритм
}

В примере ниже первые два2️⃣ аргумента функции станут именем и фамилией, а третий и последующие превратятся в массив titles[i] :

Интерактивный редактор
Результат
Loading...

Возможные ошибки

error

Остаточные параметры должны располагаться в конце, поэтому нельзя писать что-либо после них. Это вызовет ошибку:

function f(arg1, ...rest, arg2) {   // arg2 после ...rest ?
// Ошибка!
}
Запомни

...rest должен всегда быть последним.

Оператор расширения ...spread

operators

Мы узнали, как получить массив из списка параметров, но иногда нужно сделать противоположное - запихнуть массив в вызываемую функцию⚙️.

Например, есть встроенная функция⚙️ Math.max. Она возвращает наибольшее число из списка:

Интерактивный редактор
Результат
Loading...

Не так все просто

Index_finger

Допустим, у нас есть массив чисел [3, 5, 1]. Как вызвать для него Math.max?

Просто так их не вставишь — Math.max ожидает получить список чисел, а не один массив.

Интерактивный редактор
Результат
Loading...

Конечно, мы можем вводить числа вручную: Math.max(arr[0], arr[1], arr[2]).

Но, во-первых, это плохо выглядит, а, во-вторых, мы не всегда знаем, сколько будет аргументов. Их может быть как очень много, так и не быть совсем.

Вхождение параметров

Transform

Тут нам поможет оператор расширения ...spread. Он похож на остаточные параметры – тоже использует ..., но делает совершенно противоположное.

Когда функционал⚙️ ...spread используется при вызове функции⚙️, он преобразует массив-объект arr в список аргументов.

Для Math.max :

Интерактивный редактор
Результат
Loading...

Этим же способом мы можем передать несколько итерируемых объектов :

Интерактивный редактор
Результат
Loading...

Круто! Очень гибкий подход к программированию. Можно также комбинировать оператор расширения с обычными значениями.

Слияния массивов

Merger

Оператор расширения ...spread можно использовать и для слияния массивов :

Интерактивный редактор
Результат
Loading...

Преобразование в строку

Transform

Функционал⚙️ оператора расширения ...spread работает с любым перебираемым объектом.

Например, оператор расширения подойдёт для превращения строки в массив символов :

let str = 'Привет, Alex!'
let result = [...str]

spread

Посмотрим, что происходит. Под капотом оператор расширения использует итераторы, чтобы перебирать элементы. Так же, как это делает for..of.

Цикл for..of перебирает строку как последовательность символов, поэтому из ...str получается "П", "р", "и", "в", "е", "т"... Получившиеся символы собираются в массив при помощи стандартного объявления массива [...str].

Для этой задачи мы можем использовать и Array.from. Он тоже преобразует перебираемый объект (такой как строка) в массив :

let str = 'Привет'
Array.from(str) // "П", "р", "и", "в", "е", "т"
// Array.from преобразует перебираемый объект в массив

spread

Результат аналогичен [...str]. Но между Array.from(obj) и [...obj] есть разница:

  • Array.from работает как с псевдомассивами, так и с итерируемыми объектами.
  • Оператор расширения ...spread работает только с итерируемыми объектами.

Поэтому Array.from — более универсальный метод.

Итого

Elipsis

Когда мы видим "..." в коде , это могут быть как остаточные параметры ...rest, так и оператор расширения ...spread.

Как отличить их друг от друга:

  • Если ... располагается в конце списка аргументов функции, то это "остаточные параметры". Он собирает остальные неуказанные аргументы и делает из них массив.
  • Если ... встретился в вызове функции или где-либо ещё, то это "оператор расширения". Он извлекает элементы из массива для инициализации работы функции.

Полезно запомнить:

  • Остаточные параметры используются, чтобы создавать новые функции с неопределённым числом аргументов.
  • С помощью оператора расширения можно вставить массив в функцию, которая по умолчанию работает с обычным списком аргументов.
  • Вместе эти конструкции помогают легко преобразовывать наборы значений в массивы и обратно.

EnglishMoji!

Проблемы?

Problem

Пишите в Telegram или ВКонтакте, а также подписывайтесь на наши новости

Вопросы

Question

Если ... располагается в конце списка аргументов функции, то мы имеет дело с:

  1. Остаточным параметром
  2. Оператором расширения
  3. Случайными показателями

Для создания функции с неопределённым числом аргументов используют:

  1. Остаточные параметры ...rest
  2. Оператор расширения ...spread
  3. Внешние функции вызова

Объединить два массива в один можно используя:

  1. Оператор расширения ...rest
  2. Оператор расширения ...spread

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

EnglishMoji!

Ссылки

  1. MDN web doc. Статья "spread syntax"
  2. Статья "Остаточные параметры и оператор расширения"
  3. Статья "Оператор spread и rest"

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Dmitriy K.


Dmitriy Vasilev

💵

Resoner2005

🐛 🎨 🖋

Navernoss

🖋 🐛 🎨