Что означают три точки в JavaScript

Что означают три точки в JavaScript

Лайфхак, когда мы не знаем точно, сколько будет аргументов или параметров у функции

Во вчерашней статье про сортировку слиянием мы использовали такой код в конце функции:

return [ ...arr, ...left, ...right ]

Судя по квадратным скобкам, мы возвращаем массив, но в нём творится что-то странное: перед каждым элементом стоят точки, да ещё каждый из этих элементов тоже массив. Рассказываем, как такое возможно и что здесь делают три точки.

Кратко главное

  • Конкретно в этом случае три точки — это оператор расширения.
  • Он «разбивает» объект на набор его элементов и отдаёт их по порядку.
  • Можно представить, что если объект — это набор чего-то в обёртке, то оператор расширения надрывает эту обёртку, и из объекта всё высыпается.
  • Оператор можно использовать и наоборот: собрать массу каких-то значений в один объект.

Простой пример. У нас есть массив problems = ['сессия', 'отчет', 'здоровье']. Если просто сказать console.log(problems), то выведется целый объект (как бы в обёртке), и работать с ним дальше нужно именно как с объектом:

console.log(problems)
> (3) ['сессия', 'отчет', 'здоровье']

Если нам не нужен объект, а нужно просто посмотреть на значения подряд, то делаем так:

console.log(...problems)
> сессия отчет здоровье

А теперь наоборот. Допустим нам нужна функция, которая разом решает все проблемы, но мы не знаем, сколько этих проблем будет. Тогда этот оператор примет любое количество значений и соберёт их в один объект:

function solve(...allProblems){ }

Теперь эта функция примет любое число значений и уложит их в общий массив allProblems.

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

Три точки в JavaScript имеют два значения: они обозначают остаточные параметры или работают как оператор расширения. В нашем примере с функцией это как раз оператор расширения, поэтому начнём с него.

Смысл оператора расширения — преобразовать объект в перечислимый список. При этом сам объект тоже должен содержать значения, которые можно посчитать и к которым можно обратиться по отдельности. Например, это может быть массив — можно перечислить по очереди всё его содержимое. Или это может быть строка — мы можем перебрать в ней каждый символ.

На практике это может работать так. Допустим, у нас есть массив с числами, и нам нужно найти наибольшее из них:

var a = [2,7,3, 5, 4];

Но если мы используем обычную команду поиска максимума Math.max(a), то ничего не выйдет: ей нужно несколько чисел, а не один большой объект:

Что означают три точки в JavaScript

Чтобы обойти это ограничение, используют оператор расширения — он сделает из массива отдельные значения, которые будут использоваться как параметры. В этом случае вызов команды будет выглядеть так: Math.max(...a)

Что означают три точки в JavaScript

Получается, что мы расширили наш объект и виртуально превратили его из единого целого в несколько отдельных значений. 

Вернёмся к нашему примеру:

return [ ...arr, ...left, ...right ]

Теперь, зная как работает оператор расширения, мы понимаем, что функция возвращает массив (потому что квадратные скобки), который собирается из трёх частей:

  1. Сначала в массив войдут все элементы массива arr (а не сам массив).
  2. Потом все элементы массива left.
  3. И напоследок — все элементы массива right.

Самое интересное, что если какой-то элемент окажется пустым, то от него не войдёт ничего. Вот как это работает на практике: допустим, у нас есть три массива:

  • в arr будет лежать [2,7,0];
  • массив left будет пустым;
  • а в right — [1,2].

Тогда команда return [ ...arr, ...left, ...right ] вернёт такой массив: [2,7,0,1,2].

Остаточные параметры

Второй способ применения трёх точек в JavaScript — использовать их как остаточный параметр. По сравнению с оператором расширения остаточный параметр работает ровно наоборот: он собирает все значения в один массив. Чтобы было проще понять, покажем на примере.

Допустим, у нас есть функция, которая складывает переданные ей параметры и возвращает сумму:

function s(a, b) {
  return a + b;
}

Но эта функция может работать только с двумя параметрами: если ей передать три, то она отбросит лишние и не будет их учитывать при расчётах:

Что означают три точки в JavaScript

А вот с помощью остаточных параметров мы можем собрать все аргументы вместе в один массив, а потом просто перебрать его и найти сумму всех значений:

function s(...args) {
  // тут будет храниться промежуточная сумма
  let sum = 0;
  // перебираем все элементы массива args и добавляем их к сумме
  for (let arg of args) sum += arg;
  // возвращаем сумму 
  return sum;
}

console.log(s(2,4,6,8,10))
Что означают три точки в JavaScript

Этот приём можно использовать везде, где вы точно не знаете, сколько значений нужно будет обработать, но при этом нужно заранее предусмотреть все возможные ситуации.

Текст:

Михаил Полянин

Редактор:

Максим Ильяхов

Художник:

Алексей Сухов

Корректор:

Ирина Михеева

Вёрстка:

Кирилл Климентьев

Соцсети:

Виталий Вебер

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Что такое «Докер» и зачем он нужен
Что такое «Докер» и зачем он нужен

Это как полуфабрикаты из супермаркета, только с программами.

easy
Как программируют Arduino

Многие думают, что на языке Wiring, но на самом деле…

medium
Мобильная разработка для iOS и Android — что лучше и с чего начать?
Мобильная разработка для iOS и Android — что лучше и с чего начать?

Статья для тех, кто не знает, что выбрать

medium
Что такое API
Что такое API

Это как нанять внешнего сотрудника на удалёнку.

medium
Объясняем объекты

Главное понятие современных подходов к программированию.

hard
Системный администратор — что нужно знать, чтобы получать 160 000 рублей
Системный администратор — что нужно знать, чтобы получать 160 000 рублей

Это не тот администратор, который ставит вам Windows.

easy
130 тысяч рублей за работу бэкенд-разработчика. Что это значит?
130 тысяч рублей за работу бэкенд-разработчика. Что это значит?

Что нужно делать, чтобы получать столько же.

easy
Markdown: что это и кому нужно
Markdown: что это и кому нужно

Для всех, кто пишет контент, сайты и программы.

easy
Решение матричных уравнений
Решение матричных уравнений

Финальная глава саги.

medium
«Нормально делай и нормально будет»
«Нормально делай и нормально будет»

Даниил Попов о современной андроид-разработке, пользе твиттера и уходе из Авито.

easy
easy