为什么JavaScript没有严格的大于/小于比较运算符?

89

虽然 JavaScript 的类型严格比较运算符(===!==)很好用,但它没有相应的严格比较大小的运算符。

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)

为什么不呢?我问这个问题时完全预料到答案可能是“嗯,因为它不行”,但无论如何我还是问了,以防有一些有趣和/或令人沮丧的历史原因导致这些运算符被省略。


4
一道类似的问题,关于克服此限制的方法:https://dev59.com/P2cs5IYBdhLWcg3wJgpV - mwcz
5个回答

44
我只能猜测-
如果 a === b 是假的,则 a !== b 总是真的。
但是,这个推论不适用于 <== 如果 x <== 20 是假的,我们不能推断出 x >== 20 的结果,因为它可能是由于类型检查或关系检查导致的假。
我认为这有点令人困惑,虽然语言中还有很多更糟糕的东西(例如类型强制转换)。
然而,我认为严格的 <> 行为始终一致。

20
这种推理在 JavaScript 的现实中不成立。尝试 5 > "hello"5 <= "hello"。两者都是 false,因此暗示无论如何都不成立。即使进行强制转换,您所建议的问题仍然存在。 - jpmc26
如果类型不匹配,抛出异常怎么样? - Ayxan Haqverdili

31

由于a === btypeof a == typeof b && a == b的简写方式,因此您可以使用这个展开式来比较不等式:typeof a == typeof b && a <= b,例如。


12
我的问题是“为什么”,而不是“如何”。请参考我发布的链接,了解关于“如何”的讨论。 - mwcz
3
+1,解释得很好! ;) 我想补充说明一下:=== 检查篮子中的水果类型是否相同,无法确定苹果 >== 橙子这样的定性比较。这也许回答了“为什么”的问题? - TildalWave
这还正确吗?因为我一直在阅读文档和确定相等性的算法。他们网站上说==使用===而不是反过来...例如,如果它们是相等类型,则==使用===。如果它们是不同类型,则操作数将转换为相同类型,然后再次使用=== - Renzhentaxi Baerde
@user3475902 - 是在谁的网站上说的?ECMA 262第6版,7.2.12规定,如果操作数的类型相同,则只有使用===。 如果类型不同,则尝试强制转换。因此,是的,这个答案仍然是正确的,因为比较类型在功能上等同于===的标准(虽然称其为“简写”并不完全准确)。 - JDB

8
我不确定你的问题是否有答案。我的猜测是,它的预期用途是将数字与字符串(也许还有布尔值)进行比较。对于这些情况,它确实可以工作,就像非严格相等运算符一样。任何其他情况都受到任意类型强制转换规则的影响。"[] < {}" 的“正确”输出是什么?false吗?也许是undefined吗?请注意,类型甚至不需要不同,({foo: 1}) < {bar : 2}也没有任何意义。
在我看来,Brendan Eich以及ECMAScript委员会只是决定相信开发人员只会比较有意义的东西。或者甚至没有考虑开发人员会尝试疯狂的比较。为比较创建额外的运算符只会使语言变得混乱。不要忘记,在处理类型强制转换时,比较并不是唯一的陷阱,还有加减等。所以我想他们只是决定遵循允许不同类型之间进行操作的决定。他们认为这会帮助那些知道自己在做什么的人,但也许没有预料到所有的混乱会从中产生。

0
我会说问题在于严格相等可以针对不同类型进行很好的定义(非相同类型,即不相等),但关系运算符不能针对不同类型进行很好的定义。
假设我们将严格比较器 a <== b 定义为 typeof a == typeof b && a <= b。a >== b 也是如此。然后,我们比较 a = "3" 和 b = 3,结果是 a <== b false、 a >== b false 和 a === b false。恭喜,你刚刚创造了一个悖论!
这样的严格比较器仍会破坏排序算法或比较意外值之类的事情。例如:
for (var i; i <== list.count; i++) {
  doStuff(i);
}

请注意,示例错误地使用了list.count而不是list.length,这将返回undefined,当与i <== undefined进行比较时,将返回false,因此for循环将被完全跳过,这会让程序员感到惊讶。
如果JavaScript在Undefined Property上引发错误,并且比较不同类型也是如此,那么它会更好。
这意味着,实际的解决方案是开始使用预处理器,或者只是说“嗯”,并继续输入JavaScript ¯\_(ツ)_/¯ 跨类型比较应该像其他任何体面的语言一样引发异常。

0
为了说明为什么拥有它没有意义,考虑以下内容...
var x = 10
var less = (x <= 5)

现在,两者都

x <== 5

x <== '5'

会是假的,但原因不同。在第一种情况下,您可以使用 x > 5 的假设,但在后一种情况下则不行。为避免错误的假设,最好先使用 === 或 !==,然后再进行比较。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接