Lo-Dash sortBy массив дат в строковом формате

Я хотел бы знать, почему lodash не сортирует массив дат в строчном формате по сравнению с простым javascript sort(). Ожидается ли поведение или ошибка?

array = ["2014-11-11", "2014-11-12", null, "2014-11-01", null, null, "2014-11-05"]

_.sortBy(array);
// ["2014-11-11", "2014-11-12", null, "2014-11-01", null, null, "2014-11-05"]

_.sortBy(array, function(value) {return new Date(value);});
// [null, null, null, "2014-11-01", "2014-11-05", "2014-11-11", "2014-11-12"]

array.sort()
// ["2014-11-01", "2014-11-05", "2014-11-11", "2014-11-12", null, null, null]

Используемая версия: Lo-Dash v2.4.1 - Современная сборка.

Ответ 1

Если вы посмотрите на код lodash, вы можете увидеть, как он реализован. Функция _.sortBy внутри использует native Array.prototype.sort (см. источник). Но корня нет. Более интересной является функция compareAscending, которая передается как обратный вызов родного sort (источника). Итак, в нескольких словах ваш

_.sortBy(array, function(value) {return new Date(value);});

преобразуется в:

array.sort(function(a, b) {
    var aa = new Date(a),
        bb = new Date(b);

    if (aa !== bb) {
        if (aa > bb) { return 1; }
        if (aa < bb) { return -1; }
    }
    return aa - bb;
})

Итак, почему null в начале? Поскольку new Date(null) возвращает Thu Jan 01 1970 01:00:00, который меньше любой другой даты в вашем массиве.

Как насчет native sort? Согласно спецификации (см. здесь) Порядок сортировки по умолчанию соответствует строковым кодам Unicode. Если просто - native sort преобразует элементы в строки и сравнивает строки. Так что родной сорт выглядит как:

_.sortBy(array, function(value) {return value + ''; });

Как только строка "null" всегда "больше", чем строка даты (например, "2014-11-11" ) - null будет в хвосте массива результатов.