Lors de la lecture de la source de D3.js, j'ai vu le motif x >= x
. S'il s'agit de détecter des NaN parmi les nombres, pourquoi pas simplement isNaN(x)
ou x == x
?
Source, où je l'ai rencontré :
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;
};
D'après mes recherches, d3.min
Est censé fonctionner sur tout type de valeurs ordonnables, pas seulement sur les nombres. isNaN
ne fonctionnerait que des nombres.
d3 utilisait en fait ==
à un moment donné. Ce commit a introduit le test x == x
:
Contrairement à
Math.min
EtMath.max
, Il n'est pas logique de renvoyer l'infini négatif ou positif pourd3.min
Etd3.max
; les fonctions D3 renvoient la valeur minimale selon un ordre arbitraire et non par valeur numérique. Au lieu de cela, le minimum ou le maximum d'un tableau vide, ou d'un tableau qui ne contient que des valeurs dégénérées, doit toujours être indéfini.
Ce commit a changé x == x
En x <= x
(Qui a ensuite été changé en x >= x
):
En plus de
NaN
, qui n'est pas égal à lui-même, vous pouvez avoir des objets qui ne sont pas ordonnables en raison des fonctions valueOf définies qui renvoient NaN. Par exemple:var o = new Number(NaN);
Ici,
o == o
Est vrai, maiso <= o
Est faux. Par conséquent, il était possible pour d3.min, d3.max et d3.extent d'observer ces valeurs non ordonnables plutôt que de les ignorer comme prévu. Le correctif consiste à vérifier!(o <= o)
plutôt queo == o
.
OK, je vois que x >= x
Donne false
pour NaN
et undefined
. (Contrairement à isNaN(x)
ou x == x
.)
EDIT: Bien qu'il s'agisse d'un des cas d'utilisation de x >= x
, Dans ce cas (thx @Felix Kling pour l'avoir signalé) undefined
est déjà en cours de vérification.