Почему метод splice в JavaScript возвращает вырезанные элементы и является ли он мутабельным
Что проверяют
Понимаете ли вы сигнатуру splice целиком и осознаёте ли, что он единственным вызовом умеет удалять, вставлять и заменять. Вопрос про возвращаемое значение нужен, чтобы поймать путаницу с slice.
Как отвечать
splice(start, deleteCount, ...items) меняет исходный массив: вырезает deleteCount элементов начиная с индекса start и вставляет на их место переданные. Возвращает он массив удалённых элементов, всегда массив, даже пустой, если удалять было нечего.
const a = [1, 2, 3, 4];
const cut = a.splice(1, 2, 9);
// cut: [2, 3], a: [1, 9, 4]Возврат вырезанного это следствие того, что метод разрушающий: значения после вызова взять уже негде, и без такого возврата пришлось бы копировать кусок заранее. Заодно удобно для сценариев вроде перемещения элемента: вырезали, вставили в другое место.
Детали, которые стоит назвать сразу: отрицательный start отсчитывается с конца, пропущенный deleteCount означает удаление до конца массива, deleteCount равный нулю превращает вызов в чистую вставку, а число вставляемых элементов не обязано совпадать с числом удаляемых, длина меняется.
Иммутабельный аналог называется toSpliced и принимает те же аргументы, возвращая новый массив. Руками то же делается склейкой двух slice.
Где спотыкаются
Ждут, что splice вернёт изменённый массив, по аналогии со slice или map. Присваивают результат переменной, дальше работают с ней и не замечают, что в руках только вырезанный кусок, а изменённый массив это исходная переменная.
Удаляют элементы в цикле по возрастанию индекса. После каждого вызова хвост сдвигается влево, и следующий элемент пропускается: из двух соседних совпадений удаляется одно. Идти надо с конца либо собирать новый массив через filter.
Пишут splice(i) в расчёте удалить один элемент. Без второго аргумента вырезается весь хвост от индекса, а splice(0) очищает массив целиком и возвращает его копию.