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



Оператор расширения позволяет расширять выражения в тех местах, где предусмотрено использование нескольких аргументов (при вызовах функции) или ожидается несколько элементов (для массивов)

Источники http://www.codewars.com/kata/572ab0cfa3af384df7000ff8
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Spread_operator

Да. Это базовые понятия JavaScript. Правда, пока ничего непонятно
Смотрим примеры:

function plus(a, b, c, d, e) {
  return a + b + c + d + e;
}


var arg1 = [1, 2, 3, 4, 5];


plus(...arg1); // 15


Функция складывает пять чисел. Ок. Ей предлагают в качестве аргумента массив из пяти чисел.
Так написать нельзя:
plus([1, 2, 3, 4, 5]);
Потому что массив это только один аргумент. Остальные аргументы отсутствуют и функция считает их undefined. В результате получится что-то вроде
"1,2,3,4,5undefinedundefinedundefinedundefined"
Печальное зрелище.
 
Получается, что если нужно предложить в качестве аргумента массив, присваиваем его переменной а затем используем оператор расширения (три точки)

Массив может быть только одним из аргументов.
Так тоже можно

var arg2 = [2, 3];
plus(1,...arg2,4,5); // 15

Немного запутанно. Сложили шесть чисел.
1 потом 2 и 3 в массиве. Потом ещё 2, 4, 5. Последнее пять лишнее и отбрасывается, функция складывает пять первых чисел. Получается 1 + 2 + 3 + 2 + 4 = 12.
Да. Не получается. Что же складывает эта функция и почему в результате у неё получается 15?

Разобралась. Никаких шести чисел не было. Опять мы складываем 1 + 2 + 3 + 4 + 5 = 15.

Оператор расширения позволяет вставить один массив в другой

var a = [1, 2, 3]
var b = [...a, 4, 5] // [ 1, 2, 3, 4, 5 ]


Последний пример использования оператора расширения - поменять местами значения в массиве

var [a, b] = [1, 2];   // a = 1, b = 2;

Предположим, нам нужно, чтобы a = 2, b = 1 (зачем бы нам это понадобилось? Ладно, может и нужно)

Раньше для этого использовали временную переменную с, ей присваивали а, потом а присваивали b, потом b присваивали с.

var [a, b] = [1, 2]
var c = a;

a = b;
b = c; // a = 2, b = 1 


Получилась карусель. Зато весело.
Был, кстати, ещё вариант с побитовыми операторами, правда, немного замороченный

function swapper(a, b) {
        a = b ^ a; // заменяет временную переменную, которая не равна ни а, ни b, но из которой их легко получить
        b = a ^ b; // получается b = b ^ a ^ b => а
        a = a ^ b;  // получается a = b ^ a ^ a => b
        return [a, b]
    }
 
Сейчас можно сделать проще

var [a, b] = [1, 2];
[b, a] = [a, b]; // a = 2, b = 1 


Проще-то проще. Только где здесь оператор расширения, который три точки?
Вот оно что. Оказывается, элементов в массиве может быть больше двух. Например, так

var [a,...b] = [1, 2, 3, 4, 5];
Здесь а = 1, b = [2, 3, 4, 5]

Странно это (

Продолжим.
Можно и так:

function plus(...num) {
  var sum = 0
  for (x of num) sum += x;
  return sum;
}
 

plus(1, 2); // 3
plus(3, 4, 5); // 12


Здесь ...num в функции означает какое-то никому неизвестное количество аргументов, которые нужно складывать.

Последний пример - умножение каждого элемента массива на число

function mul(a, ...b) {
  for (var i = 0; i < b.length; i++) b[i] *= a;
  return b;
}
 

mul(2, 1, 1, 1); // [2,2,2]
mul(2, 1, 2, 3, 4); // [2,4,6,8]