Изменяется ли исходный массив при вызове метода sort в JavaScript и почему
Что проверяют
Знаете ли вы, какие методы массива мутирующие, и помните ли про сравнение строк по умолчанию. Оба факта регулярно дают ошибки в реальном коде.
Как отвечать
Да, sort сортирует массив на месте и вдобавок возвращает ссылку на тот же массив, а не копию. Поэтому присваивание результата новой переменной ничего не спасает: обе переменные указывают на один массив.
Вторая часть ответа не менее важна: без функции сравнения элементы приводятся к строкам и сортируются лексикографически. Отсюда знаменитое:
[10, 9, 100].sort(); // [10, 100, 9]
[10, 9, 100].sort((a, b) => a - b); // [9, 10, 100]Как не изменять исходный массив:
- копия перед сортировкой:
[...arr].sort(cmp)илиarr.slice().sort(cmp); - современный неизменяющий метод
toSorted(cmp), у которого есть родственникиtoReversed,toSplicedиwith.
Полезно перечислить, какие методы мутируют, а какие нет. Мутируют: sort, reverse, splice, push, pop, shift, unshift, fill, copyWithin. Не мутируют: map, filter, slice, concat, flat, а также новая четвёрка выше.
Практический контекст, который стоит назвать: в React мутация массива состояния не вызовет перерисовку, потому что ссылка не изменилась. Именно sort прямо по состоянию это частая ошибка, которая выглядит как «список не обновляется».
Где спотыкаются
Сортируют пропсы или состояние напрямую и удивляются отсутствию обновления интерфейса.
Забывают функцию сравнения для чисел.
Считают, что сортировка стабильна не везде: в современных движках она стабильна по спецификации, но в очень старых окружениях это не гарантировалось.