Сказка о трех точках в JavaScript
«Давным-давно»… произошло существенное обновление языка Javascript под названием ES6/ES2015. В нем появилось много разных новых функций. Одной из них были три последовательные точки, которые мы можем написать перед любым совместимым контейнером (object, array, string, set, map). Эти крошечные маленькие точки позволяют нам писать более элегантный и лаконичный код. В этой статье я расскажу, как работают три точки, и покажу наиболее распространенные варианты использования.
Три последовательные точки имеют два значения: оператор spread и оператор rest.
Оператор Spread
Оператор spread позволяет как бы расширять итерируемый контейнер или приемник. В качестве контейнера или приемника могут быть, такие объекты как array, object, set, map. Так же можно поместить части контейнера индивидуально в другой контейнер.
Пример использования оператора spread:
const newArray = ['first', ...anotherArray];
Параметры функции c оператором Rest
Синтаксис параметров позволяет нам представлять неопределенное количество аргументов в виде массива. Именованные параметры должны быть перед параметрами rest.
Пример использования оператора rest:
const func = (first, second, ...rest) => {};
Сценарии использования
Определения могут быть полезны, но по ним трудно понять идею использования. Я думаю, что варианты использования могут принести недостающее понимание определений.
Копирования массивов
Когда нам нужно видоизменить массив, но мы не хотим изменить исходный массив, тогда нам нужно скопировать его.
const fruits = ['apple', 'orange', 'banana']; const fruitsCopied = [...fruits]; // ['apple', 'orange', 'banana'] console.log(fruits === fruitsCopied); // false // old way fruits.map(fruit => fruit);
Тут выбирается каждый элемент внутри исходного массива и помещается в новую структуру массива. Один из старых способов копирования массива с помощью оператора map и создания тождественного отображения.
Уникализация массив
Если нам нужно убрать повторяющиеся элементы из массива. Какое самое простое решение?
Объект Set хранит только уникальные элементы и может быть заполнен массивом. Он также является итеративным, поэтому мы можем применить оператор spread на него, и мы получаем массив с уникальными значениями.
const fruits = ['apple', 'orange', 'banana', 'banana']; const uniqueFruits = [...new Set(fruits)]; // ['apple', 'orange', 'banana'] // old way fruits.filter((fruit, index, arr) => arr.indexOf(fruit) === index);
Объединение массивов
Мы можем объединить два отдельных массива с помощью метода concat, но почему бы не использовать оператор spread для этого?
const fruits = ['apple', 'orange', 'banana']; const vegetables = ['carrot']; const fruitsAndVegetables = [...fruits, ...vegetables]; // ['apple', 'orange', 'banana', 'carrot'] const fruitsAndVegetables = ['carrot', ...fruits]; // ['carrot', 'apple', 'orange', 'banana'] // old way const fruitsAndVegetables = fruits.concat(vegetables); fruits.unshift('carrot');
Передача аргументов как массив
При передаче аргументов оператор spread начинает делать наш код более читабельным. До ES6 нам приходилось использовать оператор arguments. Теперь мы можем просто использовать spread, что приведет к гораздо более чистому коду.
const mixer = (x, y, z) => console.log(x, y, z); const fruits = ['apple', 'orange', 'banana']; mixer(...fruits); // 'apple', 'orange', 'banana' // old way mixer.apply(null, fruits);
Нарезка массива
Проще конечно же срезать с помощью метода slice, но если мы хотим, мы можем использовать оператор spread. Но в этом случае мы должны поименно называть оставшиеся элементы один за другим, так что это не лучший способ вырезать из середины большого массива.
const fruits = ['apple', 'orange', 'banana']; const [apple, ...remainingFruits] = fruits; // ['orange', 'banana'] // old way const remainingFruits = fruits.slice(1);
Преобразовать аргументы в массив
arguments в Javascript — это объекты, похожие на массивы. Вы можете получить к нему доступ с помощью индексов, но вы не можете вызывать методы массива, такие как map, filter. arguments — это итеративный объект, так что мы можем с ним сделать? Поставить перед ним три точки и получить доступ к нему как к массиву!
const mixer = (...args) => console.log(args); mixer('apple'); // ['apple']
Конвертировать NodeList в array
arguments похожи на NodeList, возвращаемый функцией querySelectorAll. Они также ведут себя как массив, но не имеют соответствующих методов.
[...document.querySelectorAll('div')]; // old way Array.prototype.slice.call(document.querySelectorAll('div'));
Копирование объекта
Наконец, мы добрались до объектных манипуляций. Копирование работает так же, как с массивами. Ранее это было возможно с Object.assign и пустым литералом объекта.
const todo = { name: 'Clean the dishes' }; const todoCopied = { ...todo }; // { name: 'Clean the dishes' } console.log(todo === todoCopied); // false // old way Object.assign({}, todo);
Объеденение объектов
Единственное отличие в слиянии заключается в том, что свойства с одним и тем же ключом будут перезаписываются. Самое правое свойство имеет наивысший приоритет.
const todo = { name: 'Clean the dishes' }; const state = { completed: false }; const nextTodo = { name: 'Ironing' }; const merged = { ...todo, ...state, ...nextTodo }; // { name: 'Ironing', completed: false } // old way Object.assign({}, todo, state, nextTodo);
Важно отметить, что слияние создает копии только на первом уровне иерархии.
Разбиение строки на символы
Последний пример со строками. Можно разбить строку на символы с помощью оператора spread. Конечно, это то же самое, если бы вы вызывали метод split с пустой строкой.
const country = 'USA'; console.log([...country]); // ['U', 'S', 'A'] // old way country.split('');
Вот и все
В этой статье мы рассмотрели много разных вариантов использования для трех точек в Javascript. Как вы можете видеть, ES6 не только сделал более эффективным написание кода, но также представил несколько забавных способов решения давно существующих проблем. Теперь все основные браузеры поддерживают новый синтаксис; Все приведенные выше примеры можно попробовать в консоли браузера при чтении этой статьи. В любом случае, используйте оператор spread и rest, если вы раньше этого не делали. Это отличное дополнение к языку, который все должны знать.
Оригинальная статья: Gábor Soós — The tale of three dots in Javascript