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

Что означают три точки в 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), то ничего не выйдет: ей нужно несколько чисел, а не один большой объект:

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

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

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

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;
}

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

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

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

console.log(s(2,4,6,8,10))

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

Художник:

Даня Берковский

Корректор:

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

Вёрстка:

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

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