Al leer el código fuente de D3.js, vi el patrón x >= x . Si es para detectar NaN entre números, ¿por qué no simplemente es isNaN(x) o 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; };Según mis investigaciones, se supone que d3.min funciona en cualquier tipo de valores ordenables, no solo números. isNaN solo funcionaría con números.
d3 en realidad estaba usando == en algún momento. Este compromiso introdujo la prueba x == x :
A diferencia
Math.minyMath.max, no tiene sentido devolver infinito negativo o positivo parad3.minyd3.max; las funciones D3 devuelven el valor mínimo según un orden arbitrario, no por valor numérico. En cambio, el mínimo o el máximo de una matriz vacía, o una matriz que contiene solo valores degenerados, siempre debe estar indefinido.
Esta confirmación cambió x == x a x <= x (que luego se cambió nuevamente a x >= x ):
Además de
NaN, que no es igual a sí mismo, puede tener objetos que no se pueden ordenar debido a funciones valueOf definidas que devuelven NaN. Por ejemplo:var o = new Number(NaN);Aquí,
o == oes verdadero, peroo <= oes falso. Por lo tanto, era posible que d3.min, d3.max y d3.extent observaran estos valores no ordenables en lugar de ignorarlos según lo previsto. La solución es verificar!(o <= o)en lugar deo == o.
OK, veo que x >= x da false tanto para NaN como para undefined . (A diferencia isNaN(x) o x == x .)
EDITAR: Si bien es uno de los casos de uso de x >= x , en este caso (gracias a @Felix Kling por señalar esto) ya se está verificando undefined .