Pourquoi JavaScript n'a-t-il pas des opérateurs de comparaison plus stricts / inférieurs?

Alors que les opérateurs de comparaison de type JavaScript ( === !== ) sont gentils, il n'a pas de comparaisons strictes correspondantes pour plus ou moins.

 var x = 10; x <= 20; // true x <= '20'; // true x <== 20; // true (or would be, if JS had such an operator) x <== '20'; // false (ditto) 

Pourquoi pas? Je pose cette question en attendant pleinement que la réponse soit "uh, parce qu'elle ne l'est pas", mais je demande tout de même, au cas où il y a une raison historique intéressante et / ou décourageante pour l'omission de ces opérateurs.

Je ne peux que deviner –

Si
a === b est faux, puis
a !== b est vrai. Toujours .

Mais, cette implication ne tiendrait pas pour <==

Si
x <== 20 est faux, nous ne pouvons pas déduire le résultat de x >== 20 car il a peut-être été faux en raison de la vérification du type ou de la vérification de la relation.

Je pense que c'est un peu confus, bien qu'il y ait beaucoup de choses dans la langue qui sont bien pires (tapez la coercition en général, pour en nommer un).

Cependant, je pense qu'un strict < ou > se comporterait constamment.

Puisque a === b est un raccourci pour typeof a == typeof b && a == b , vous pouvez utiliser cette expansion pour les inégalités: typeof a == typeof b && a <= b par exemple.

Je ne suis pas sûr de répondre à votre question. Je suppose que l'utilisation prévue consiste à comparer les nombres aux chaînes (et peut-être les booléens). Il fonctionne réellement pour ces cas, comme le fait l'opérateur d'égalité non strict. Toute autre chose est soumise à des règles de coercition de type arbitraire de toute façon. Quelle serait la sortie "correcte" de [] < {} ? false ? Peut-être undefined ? Notez que les types n'ont même pas besoin d'être différents, ({foo: 1}) < {bar : 2} n'a pas non plus de sens.

À mon avis, ils (Brendan Eich, et plus tard le comité ECMAScript) ont simplement décidé de croire que les développeurs ne compareraient que des comparaisons raisonnables. Ou même pas considéré que les développeurs essayeraient des comparaisons folles. La création d'opérateurs supplémentaires à des fins de comparaison ne fera que encombrer la langue. Et n'oubliez pas que les comparaisons ne sont pas les seuls pièges lors de la contrainte de type, il y a aussi ajout, soustraction, etc. Donc, je suppose qu'ils ont simplement décidé d'être fidèles à leur décision d'autoriser les opérations entre différents types. Ils pensaient que cela aiderait les gens quand ils savaient ce qu'ils faisaient, mais peut-être ne prévoyait-il pas toute la confusion qui en résultait.

Pour montrer pourquoi il n'a pas de sens de l'avoir, pensez à la place …

 var x = 10 var less = (x <= 5) 

Maintenant, les deux

 x <== 5 

et

 x <== '5' 

Serait faux, mais pour des raisons différentes. En premier lieu, vous pouvez utiliser l'hypothèse que x> 5, mais pas dans le dernier cas. Pour éviter de fausses hypothèses, il est préférable d'utiliser === ou! == d'abord puis de comparer après.

Je dirais que le problème est que l'égalité stricte peut être bien définie pour différents types (pas du même type, puis pas égal), mais les opérateurs relationnels ne peuvent pas être bien définis pour différents types.

Supposons que nous définissions un comparateur strict a <== b pour être typeof a == typeof b && a <= b . Et le même pour a >== b . Ensuite, nous comparons a = "3" et b = 3 et les résultats sont a <== b faux, a >== b faux et a === b faux. Félicitations, vous venez de créer un paradoxe!

Un tel comparateur strictement égarerait toujours des choses comme des algorithmes de tri ou une comparaison de valeurs inattendues. Par exemple:

 for (var i; i <== list.count; i++) { doStuff(i); } 

Notez que l'exemple utilise de manière erronée list.count au lieu de list.length , qui retournera simplement undefined , ce qui renverrait false en comparaison de i <== undefined , donc la boucle for serait complètement ignorée pour la surprise du programmeur .

Ce serait beaucoup mieux si JavaScript a soulevé une erreur sur list.count pour Undefined Property, et aussi en comparant différents types.

C'est tout ce que je peux dire, la comparaison entre les types devrait générer une exception, tout comme tout autre langage correct là-bas. Mais ce n'est pas le cas.

Cela signifie que la solution pratique réelle est de commencer à utiliser des préprocesseurs, ou simplement dire "Oh bien" et continuer à taper JavaScript ¯\_(ツ)_/¯