Что означает запись с rest оператором в деструктуризации массива в JavaScript
Что проверяют
Читаете ли вы современный синтаксис и понимаете ли разницу между сбором остатка и раскладыванием, то есть между rest и spread. Заодно смотрят внимательность к деталям вроде обязательного порядка элементов.
Как отвечать
Три точки в левой части присваивания собирают всё оставшееся в новый массив:
const [first, second, ...rest] = [1, 2, 3, 4, 5];
// first 1, second 2, rest [3, 4, 5]Правила, которые и спрашивают:
- элемент с тремя точками обязан быть последним, запятая после него это синтаксическая ошибка;
- результат всегда массив: если брать нечего, получится пустой массив, а не
undefined; - значения по умолчанию работают для обычных элементов, для остатка их задать нельзя;
- пропуски разрешены, запись
const [, , ...tail] = arrотбрасывает первые два элемента; - деструктурируется любой итерируемый объект, не только массив: строка,
Set, результат генератора; - копия поверхностная, вложенные объекты остаются общими с исходным массивом.
Тот же синтаксис живёт в объектах (const { id, ...others } = obj) и в параметрах функции (function f(...args)), причём args это настоящий массив, в отличие от arguments.
Где спотыкаются
Путают rest и spread. Символы одинаковые, смысл противоположный: слева от знака равенства остаток собирается, справа значение раскладывается. Формально это не оператор, а часть синтаксиса, поэтому рассуждения про приоритет операторов тут ни при чём.
Ждут, что остаток можно взять с конца или из середины. Забрать последние два элемента деструктуризацией нельзя, для этого нужен slice или разворот массива.
Забывают про цену. Каждый остаток это новый массив и проход по хвосту, а на бесконечном генераторе такая запись вычерпывает итератор и подвешивает вкладку. В горячем коде дешевле взять нужный элемент по индексу.