X >= x в JavaScript

При чтении источника D3.js я видел шаблон x >= x. Если для определения значений NaN среди чисел, почему не просто isNaN(x) или x == x?

Источник, где я столкнулся с ним:

d3.min = function(array, f) {
  var i = -1, n = array.length, a, b;
  if (arguments.length === 1) {
    while (++i < n) if ((b = array[i]) != null && b >= b) {
      a = b;
      break;
    }
    while (++i < n) if ((b = array[i]) != null && a > b) a = b;
  } else {
    while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
      a = b;
      break;
    }
    while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
  }
  return a;
};

Ответ 1

Из моих исследований d3.min должен работать над любыми упорядочиваемыми значениями, а не только с числами. isNaN будут работать только числа.

d3 фактически использовал == в некоторой точке. Этот коммит представил тест x == x:

В отличие от Math.min и Math.max, нет смысла возвращать отрицательную или положительную бесконечность для d3.min и d3.max; функции D3 возвращают минимальное значение в соответствии с произвольным порядком, а не числовым значением. Вместо этого минимум или максимум пустого массива или массив, содержащий только вырожденные значения, всегда должны быть undefined.

Этот commit изменил x == x на x <= x (который позже был снова изменен на x >= x):

В дополнение к NaN, который не равен самому себе, вы можете иметь объекты, которые не упорядочиваются из-за определенных функций valueOf, которые возвращают NaN. Например:

var o = new Number(NaN);

Здесь o == o истинно, но o <= o является ложным. Следовательно, d3.min, d3.max и d3.extent могли наблюдать эти неустановимые значения, а не игнорировать их по назначению. Исправление состоит в том, чтобы проверить !(o <= o), а не o == o.

Ответ 2

Хорошо, я вижу, что x >= x дает false для NaN и undefined. (В отличие от isNaN(x) или x == x.)

EDIT: хотя это один из вариантов использования x >= x, в этом случае (спасибо @Felix Kling для указания этого) undefined уже проверяется.