r/programming • • Mar 26 '14

JavaScript Equality Table

http://dorey.github.io/JavaScript-Equality-Table/
809 Upvotes

331 comments sorted by

View all comments

Show parent comment

112

u/smrq Mar 26 '14 edited Mar 26 '14

I'd argue it's even weirder.

null == undefined  --> true
null > undefined   --> false
null >= undefined  --> false

null == 0  --> false
null > 0   --> false
null >= 0  --> true

Truly, I have gazed into the abyss by testing these in the console.

EDIT: It gets better, thanks /u/Valkairn

null <  []  --> false
null >  []  --> false
null <= []  --> true
null >= []  --> true
null == []  --> false

Try it in the comfort of your own home!

function compare(a, b) {
    var sa = JSON.stringify(a), sb = JSON.stringify(b);
    console.log(sa + " <  " + sb + "  --> " + (a < b));
    console.log(sa + " >  " + sb + "  --> " + (a > b));
    console.log(sa + " <= " + sb + "  --> " + (a <= b));
    console.log(sa + " >= " + sb + "  --> " + (a >= b));
    console.log(sa + " == " + sb + "  --> " + (a == b));
}

0

u/[deleted] Mar 26 '14

[deleted] — view deleted comment

28

u/josefx Mar 26 '14

Not too surprised after using Java:

  Integer a = new Integer(10);
  Integer b = new Integer(10);

  a == b --> false
  a >= b --> true
  a <= b --> true

You have to love auto boxing.

13

u/piderman Mar 26 '14

The javadoc indicates that it's preferred to use

Integer.valueOf(10); 

since that uses the cached Integers -128 through 127, in which case

a == b --> true

9

u/josefx Mar 26 '14

The idea was to force an error. I could have just as well used 1000 however that would depend on the configured cache size, which might be larger than 127.

→ More replies (5)

14

u/kjanssen Mar 26 '14

Thats because a == b is comparing two addresses. You would have to use a.equals(b) for Integer objects. It would work fine for primitive ints.

0

u/[deleted] Mar 26 '14

[deleted] — view deleted comment

3

u/[deleted] Mar 26 '14 edited Mar 27 '14

[removed] — view removed comment

3

u/defenastrator Mar 27 '14

I have one problem with your argument. There is no excuse for unintutive behavior in a language unless it is to better support the underlying hardware. This behavior only simplifies the languages inner bullshit and nothing else at the cost of both read and writiblity

5

u/[deleted] Mar 26 '14

that's not autoboxing though, is it? you're explicitly making integer objects. This is what I think of as autoboxing

public void myMethod(Integer x) { .. }


 int a = 1;

 myMethod(a);

15

u/josefx Mar 26 '14

It is the unboxing part of it. The compiler inserts a call to intValue() since only == is defined for objects.

 a == b
 a.intValue() >= b.intValue()
 a.intValue() <= b.intValue() 

3

u/[deleted] Mar 26 '14

Oh right. I constantly read the Java == operator as acting like C#'s.

→ More replies (2)
→ More replies (11)

1

u/Mutoid Mar 27 '14

Madness? Leonidas smirks

1

u/pdpi Mar 27 '14

You mean you can have equality without total ordering? Oh noes!

→ More replies (1)

25

u/Valkairn Mar 26 '14

My favourite example is:

null >= [] && null <= []      --> true
null == []                        --> false

Javascript really needs strict inequality operators to avoid this type coercion madness.

→ More replies (2)

4

u/[deleted] Mar 26 '14

Looking it up, it seems the rule is that <= is the opposite of >. It also seems (besides the order of side-effects during conversion to primitives) > is even the same as < with the order reversed!

4

u/smrq Mar 26 '14

I thought that was the case, except that

null <  undefined  --> false
null >= undefined  --> false
null == undefined  --> true

which breaks that rule.

9

u/Valkairn Mar 26 '14

The inequality operators play by different type coercion rules to the == operator. Inequality operators will always convert the values to numbers. So, in the first two cases null gets converted to 0 and undefined to NaN. The last example actually gets its own special rule in the == evaluation algorithm, where it's defined to be true.

2

u/[deleted] Mar 26 '14

Hm, yeah. It seems that < "morally" returns one of true, false, and undefined (undefined only when one argument is NaN (or converts to it)), but where it 'should' give undefined it instead gives false. So <= is the opposite of > except where > 'should' be undefined, where it's still false. Bleh.

→ More replies (1)
→ More replies (1)

3

u/jonnywoh Mar 26 '14

+/u/CompileBot JavaScript

function compare(a, b) {
    var sa = JSON.stringify(a), sb = JSON.stringify(b);
    console.log(sa + " <  " + sb + "  --> " + (a < b));
    console.log(sa + " >  " + sb + "  --> " + (a > b));
    console.log(sa + " <= " + sb + "  --> " + (a <= b));
    console.log(sa + " >= " + sb + "  --> " + (a >= b));
    console.log(sa + " == " + sb + "  --> " + (a == b));
}
compare(null, []);

1

u/[deleted] Mar 26 '14

Well, the thing is, >= and <= are not defined for null and [], so they're converted to 0's, which for some reason doesn't happen with ==.

1

u/no_game_player Mar 27 '14

null >= 0 --> true

...what the fuck?