95

While JavaScript's type-strict comparison operators (===, !==) are nice, it doesn't have corresponding strict comparisons for greater/less than.

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)

Why not? I ask this question fully expecting the answer to be "uh, because it doesn't", but I'm asking anyway, in case there's an interesting and/or disheartening historical reason for such operators being omitted.

1

5 Answers 5

45

I can only guess-

If
a === b is false, then
a !== b is true. always.

But, this implication wouldn't hold for <==

If
x <== 20 is false, we cannot infer the result of x >== 20 because it might have been false due to type check, or the relation check.

I think that's slightly confusing, although there's plenty of things in the language that are much worse (type coercion in general, to name one).

However, I think a strict < or > would behave consistently.

Sign up to request clarification or add additional context in comments.

2 Comments

This reasoning doesn't hold up to the reality of JavaScript. Try 5 > "hello" and 5 <= "hello". Both are false, so the implication doesn't hold anyway. The very problem you suggest already exits even with the coercion.
How about throwing an exception if types don't match?
38

Since a === b is a shorthand for typeof a == typeof b && a == b, you can use this expansion for inequalities: typeof a == typeof b && a <= b for example.

4 Comments

My question was "why", not "how". See the link I posted for a discussion of "how".
+1, good explanation! ;) I'd add that === checks for same type of fruit in the basket and that there's no way of determining weather apple >== orange. It's simply not a qualitative comparison. Maybe that answers the 'why' part?
Is this still correct? because i been reading the documentation and the algorithms for determining equality. It said on their site that == uses === and not the other way around... E.g. if they are equal type == uses ===. if they are different type then the operands are converted to the same type and then uses === again.
@user3475902 - It said on who's site? ECMA 262, 6th Edition, 7.2.12 states that === is used if and only if the types of the operands are the same. If the types are not the same, then coercion is attempted. So yes, this answer is still correct in the sense that comparing types is functionally equivalent to the standard for === (though it's not quite accurate to call it a "shorthand").
8

I'm not sure there is an answer to your question. My guess is, the intended use is for comparing numbers to strings (and maybe booleans). It actually works for those cases, as the non-strict equality operator does. Anything else is subject to arbitrary type coercion rules anyway. What would be the "correct" output of [] < {}? false? Maybe undefined? Note that the types don't even need to be different, ({foo: 1}) < {bar : 2} also doesn't make any sense.

In my opinion, they (Brendan Eich, and later the ECMAScript committee) just decided to trust that the developers would only compare things that make sense comparing. Or didn't even consider that developers would try crazy comparisons. Creating extra operators for comparison would only clutter the language. And don't forget comparisons are not the only pitfalls when dealing with type coercion, there's also addition, subtraction, etc. So I guess they just decided to be true to their decision of allowing operations between different types. They thought that would help people when they know what they're doing, but maybe didn't anticipate all the confusion that arose from that.

Comments

0

To show why it doesn't make sense to have it, consider instead...

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

Now, both

x <== 5

and

x <== '5'

would be false, but for different reasons. In the first instance, you could use the assumption that x > 5, but not in the latter case. To avoid false assumptions it is better to use === or !== first and then comparison after.

Comments

0

I'd say the problem is that strict equality can be well defined for different types (unequal types are strictly unequal), but relational operators can not be well defined for different types.

Assume we define a strict comparator a <== b to be typeof a == typeof b && a <= b. We also define a strict comparator a >== b to be typeof a == typeof b && a >= b.

If we set a = "3" and b = 3 , the results are a <== b false, a >== b false and a === b false.

Such strict comparator would mess things up like sorting algorithms or comparing unexpected values. For example:

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

Note that the example mistakenly uses list.count instead of list.length, which will just return undefined. The for loop conditional will just return false when i <== undefined is evaluated, so the for loop will be entirely skipped to the surprise of the programmer.

It would be much better if JavaScript was designed to raise an error if the type comparison were to fail with a strict comparator. For that matter it would be amazing if an error like Undefined Property were to be raised if an invalid property is accessed like list.count.

That's all I can say on this matter. Comparing across types should raise an exception, just like any other decent language out there. But it doesn't.

This means that the practical solution is to start using preprocessors like TypeScript. Or just say "Oh well" and keep typing JavaScript.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.