Элементы этого массива отсортированы. Сортировка должна быть стабильной (то есть элементы, которые сравнивают равные, должны оставаться в исходном порядке). Если comparefn не является undefined, это должна быть функция, которая принимает два аргумента x и y и возвращает отрицательное Число (Number), если x < y, положительное Число (Number), если x > y, или ноль в противном случае.
При вызове метода сортировки sort выполняются следующие шаги:
1. Если comparefn не является undefined, а IsCallable(comparefn) имеет значение false, генерировать исключение TypeError. 2. Пусть obj будет ? ToObject(значение this). 3. Пусть len будет ? LengthOfArrayLike(obj). 4. Пусть items будет новым пустым Списком. 5. Пусть k равно 0. 6. Повторить, пока k < len, а. Пусть Pk будет ! ToString(𝔽(k)). b. Пусть kPresent будет? HasProperty(obj, Pk). c. Если kPresent является true (истинно), то i. Пусть kValue будет? Get(obj, Pk). ii. Добавить kValue к items. d. Установите k на k + 1. 7. Пусть itemCount будет количеством элементов в items. 8. Сортировка элементов items с помощью определенной реализацией последовательности вызовов SortCompare. Если какой-либо такой вызов возвращает внезапное завершение, остановитесь перед выполнением любых дальнейших вызовов SortCompare или шагов в этом алгоритме и верните это завершение. 9. Пусть j равно 0. 10. Повторите, пока j < itemCount, а. Выполнять ? Set(obj, !ToString(𝔽(j)), items[j], true). b. Установите j на j + 1. 11. Повторите, пока j < len, а. Выполнять ? DeletePropertyOrThrow(obj, !ToString(𝔽(j))). b. Установите j на j + 1. 12. Вернуть obj.
Порядок сортировки (sort order) — это упорядочение после завершения этой функции значений свойств с целочисленным индексом объекта obj, чьи целочисленные индексы меньше len. Затем результат функции сортировки sort определяется следующим образом:
Порядок сортировки определяется реализацией, если выполняется одно из следующих условий:
- Если comparefn не является undefined и не является последовательной функцией сравнения для элементов items (смотри ниже).
- Если comparefn является undefined и SortCompare не действует как функция согласованного сравнения.
- Если comparefn является undefined, и все приложения ToString для любого конкретного значения, переданного в качестве аргумента в SortCompare, не приводят к одинаковому результату.
Если порядок сортировки не указан выше как определяемый реализацией, элементы items должны удовлетворять всем следующим условиям после выполнения шага 8 алгоритма, приведенного выше:
- Должна существовать некоторая математическая перестановка π неотрицательных целых чисел, меньших itemCount, такая, что для каждого неотрицательного целого числа j, меньшего, чем itemCount, элемент old[j] точно такой же, как new[π(j)].
- Тогда для всех неотрицательных целых чисел j и k, каждое из которых меньше itemCount, если SortCompare(old[j], old[k]) < 0 (смотри SortCompare ниже), то π(j) < π(k).
Здесь обозначение old[j] используется для ссылки на items[j] перед выполнением шага 8, а обозначение new[j] — для ссылки на items[j] после того, как шаг 8 был выполнен.
Функция comparefn является последовательной функцией сравнения для набора значений S, если все перечисленные ниже требования выполняются для всех значений a, b и c (возможно, одного и того же значения) в наборе S: Обозначение a < CF b означает comparefn(a, b) < 0; a = CF b означает comparefn(a, b) = 0 (любого знака); и a > CF b означает comparefn(a, b) > 0.
- Вызов comparefn(a, b) всегда возвращает одно и то же значение v, если задана конкретная пара значений a и b в качестве двух его аргументов. Кроме того, Type(v) — это Number, а v — не NaN. Обратите внимание, что это означает, что ровно одно из a < CF b, a = CF b и a > CF b будет истинным для данной пары a и b.
- Вызов comparefn(a, b) не изменяет obj или какой-либо объект в цепочке прототипов obj.
- a = CF a (рефлексивность)
- Если a = CF b, то b = CF a (симметрия)
- Если a = CF b и b = CF c, то a = CF c (транзитивность =CF)
- Если a < CF b и b < CF c, то a < CF c (транзитивность <CF)
- Если a > CF b и b > CF c, то a > CF c (транзитивность >CF)
Вышеупомянутые условия необходимы и достаточны, чтобы гарантировать, что comparefn разбивает множество S на классы эквивалентности и что эти классы эквивалентности полностью упорядочены.
Функция сортировки намеренно универсальна; это не требует, чтобы это значение было массивом. Следовательно, его можно передать другим видам объектов для использования в качестве метода.
SortCompare ( x, y )
Абстрактная операция SortCompare принимает аргументы x и y. Она также имеет доступ к аргументу comparefn, переданному текущему вызову метода сортировки sort. При вызове она выполняет следующие шаги:
1. Если x и y оба не определены (undefined), верните +0𝔽. 2. Если x не определен (undefined), верните 1𝔽. 3. Если y не определено (undefined), вернуть -1𝔽. 4. Если comparefn не undefined, тогда a. Пусть v будет ? ToNumber(? Call(comparefn, undefined, «x, y»)). b. Если v равно NaN, вернуть +0𝔽. c. Вернуть v 5. Пусть xString будет? ToString(х). 6. Пусть yString будет? ToString(y). 7. Пусть xSmaller будет результатом выполнения абстрактного реляционного сравнения xString < yString. 8. Если xSmaller истинно true, вернуть -1𝔽. 9. Пусть ySmaller будет результатом выполнения абстрактного реляционного сравнения yString < xString. 10. Если ySmaller истинно true, верните 1𝔽. 11. Вернуть +0𝔽
Примечание 1
Поскольку несуществующие значения свойств всегда сравниваются больше, чем undefined значения свойств, а undefined всегда сравнивает большее, чем любое другое значение, значения undefined свойств всегда сортируются до конца результата, за которым следуют несуществующие значения свойств.
Примечание 2
Вызов методов, выполняемых абстрактными операциями ToString на шагах 5 и 6, может привести к тому, что SortCompare не будет вести себя как функция согласованного сравнения.
Информационные ссылки
Стандарт ECMAScript — Раздел «23.1.3.28 Array.prototype.sort ( comparefn )» — https://tc39.es/ecma262/#sec-array.prototype.sort