44

I just have more of a trivial question.

Why does undefined == undefined return true, but undefined >= undefined is false?

undefined is equal to undefined.

But it is not equal to or greater?

kyun
  • 9,710
  • 9
  • 31
  • 66
  • 11
    My guess is that both `undefined`s are coerced to `NaN` which is not equal to itself. – Sebastian Simon Oct 06 '17 at 14:48
  • 1
    `undefined === undefined || undefined > undefined` and `undefined >= undefined`, the OR in "greater than or equal to" is not the same as this OR `||` – Deepak Kamat Oct 06 '17 at 14:51
  • @DeepakKamat what happens behind the scenes of `>=`? I think that's what this question is getting at – theonlygusti Oct 06 '17 at 14:51
  • `undefined` isn't number and that is what happens. `10 >= "hello world"` returns false is simple to understand. So my guess is using comparison operator on Not a Number would always return false. – Deepak Kamat Oct 06 '17 at 14:53
  • 2
    Yeah, I'd agree with Xufox. JavaScript probably tries to convert them to some comparable values, e.g. a number. But undefined converted to a number is NaN, which is neither equal to itself nor greater than itself. – theonlygusti Oct 06 '17 at 15:08
  • I have the same thought with @Xufox. Because we all know the equal operator will try to convert the type before it actually compares the value. You can refer to the link here to see how type will be converted when performing equality comparison. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness But for >= I have no idea though. – trungk18 Oct 06 '17 at 15:13
  • 1
    @trungk18 basically, it first tries to get either a string or a number if they are objects and from there on it will convert them to numbers if both of them aren't a string. – MinusFour Oct 06 '17 at 15:18
  • 8
    [wat](https://i.stack.imgur.com/WgPi4.png) – Mike G Oct 06 '17 at 17:43
  • 38
    It's Javascript. Don't attempt to use logic. – gardenhead Oct 06 '17 at 19:37
  • [Obligatory wat lightning talk](https://www.destroyallsoftware.com/talks/wat) – Denis de Bernardy Oct 07 '17 at 09:31
  • Try `x = {valueOf(){ return NaN }}; console.log(x == x, x >= x)`. The `==` operator does not always do relational comparison. – Bergi Oct 07 '17 at 10:51

3 Answers3

46

The >= operator is essentially the negation of the < operator. And both invoke the Abstract Relational Comparison Algorithm which returns undefined for undefined >= undefined as defined in step 3 (a to c). Actually, you can also see that the greater-than(-or-equal) and less-than(-or-equal) operators are only meant to work with either numbers or strings.

Then in the 6. step of the specification of the >= operator, you can see why it returns false:

If r is true or undefined, return false. Otherwise, return true.

str
  • 42,689
  • 17
  • 109
  • 127
8

undefined === undefined || undefined > undefined and undefined >= undefined, the OR in "greater than or equal to" is not the same as this OR ||.

As far as it is concerned the comparison operators like >, <, >= etc are meant for numbers and undefined isn't numbers, undefined is undefined.

What would you expect as a return value when 10 >= "Hello World"? Of course a false, but again 10 >= "10" returns true because 10 == "10" is true and 10 === "10" is false. The "10" can be converted into a number so we see the result that would have been returned in case of an actual number and not a string with numbers.

There is no strict equality operator version for >= as opposed to != which is !==

Some really weird and confusing things happen when you try comparing null, undefined, NaN - This is something that the specification of JavaScript may be able to answer and since JavaScript is a very loosely typed language and the types are very flexible that is why one can compare 10 and "10" and still get results which you may have gotten only when you compared two integers in most of the other languages.

miken32
  • 42,008
  • 16
  • 111
  • 154
Deepak Kamat
  • 1,880
  • 4
  • 23
  • 38
2

Inequality operators (<, >, and so on) cannot be used to compare values that cannot be implicitly converted to numbers. This includes undefined. The reason behind what you're seeing is that, unlike other languages that throw an error if you try to do something like this anyway (i.e. TypeError in python), JS lets you do it. However, the result will always be false.

stelioslogothetis
  • 9,371
  • 3
  • 28
  • 53
  • This doesn’t explain why `"foo" >= "bar"` is `true` and doesn’t include an explanation of how operators coerce their operands to a matching type. – Sebastian Simon Oct 06 '17 at 15:00
  • 1
    @Xufox because JavaScript is a damned loosely typed language. It can convert strings that has numbers in strings and compare and that is it also has a "===" operator to do a strict comparison instead of simple converting strings to integers and floats. – Deepak Kamat Oct 06 '17 at 15:05
  • 8
    Actually, when using inequalities, strings are compared [lexicographically](https://stackoverflow.com/a/7087831/7662085). – stelioslogothetis Oct 06 '17 at 15:07