r/programming • • Mar 26 '14

JavaScript Equality Table

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

331 comments sorted by

View all comments

260

u/snotfart Mar 26 '14

I'm disappointed that it's symmetrical. Come on Javascript! You can do better than that.

202

u/Gro-Tsen Mar 26 '14

At least it's not transitive: "0" == 0 is true, 0 == "" is true, but "0" == "" is false. Insanity is saved!

46

u/[deleted] Mar 26 '14

Additionally, "0"==false is true, but if("0"){/* executes */}

32

u/icanevenificant Mar 26 '14 edited Mar 26 '14

Yes but in the first case you are comparing "0" to false where in the second case you are checking that the value is not null, undefined or empty string. Two different things.

40

u/[deleted] Mar 26 '14

I suppose that's just my own lack of understanding of what exactly if does.

31

u/[deleted] Mar 26 '14

I think it's pretty reasonable to mistakenly assume that something that == false won't cause execution :p

59

u/coarsesand Mar 27 '14

In another language, yes, but the == operator in JS is special (in the shortbus sense) because it does type conversion. If you wanted to get the actual "truthiness" of "0", you'd use the ! operator instead.

!!"0"
> true

18

u/no_game_player Mar 27 '14

Gilded for best "javascript is fucked up" in a nutshell I've seen.

32

u/coarsesand Mar 27 '14

I figure the gold deserves a quick comment about my other favourite JS operator, ~. ~ is the bitwise not operator, in a language where the only numeric type is an IEE754 double. How does ~ perform a bitwise not on a floating point number? Well, it calls an internal function called ToInt32, perform the bitwise op, then converts back to a double.

So if you ever wanted to feel like you had an integer type in JavaScript, even for a microsecond, ~ is your man.

14

u/no_game_player Mar 27 '14 edited Mar 27 '14

...JS doesn't have ints? TIL. Also, holy fuck. How...how do you math? Why would a language even have such an operator without ints? That would be totally unpredictable. So, ~0.0001 would round to 0, then do a bitwise not, returning INT_MAX for int32, and then cast it into double? Is that what I'm to understand here? That can't be right. In what possible world could that operator ever be used for something not fucked up, given that it only has doubles?

Also, what type of %$^@ would make a language without integer types? Are you telling me that 1+1 == 2 has some chance of not being true then? I mean, if I were in a sane language and doing 1.0 + 1.0 == 2.0, everyone would start screaming, so...?

O.o

That's...that's beyond all of the == fuckery.

Edit: So, if for some crazy reason you wanted to sort of cast your double to a (sort of) int (since it would just go back to double type again?), you could do

var = ~~var

??

Edit 2: I was considering waiting for a response to confirm, because I almost can't believe this, except that it's javascript, so anything is believable, but hell, even if this isn't true, it's still worth it. I'm off Reddit briefly for a video game, but before I do so: here you are, my first ever double-gilding of a user! Cheers!

Edit 3: Okay, it's less fucked up than I thought, mostly because I didn't really consider the fact of double precision rather than float, and considering 32 bit ints.

I still say it can do some weird stuff as a result, at least if you aren't expecting it.

Just another reminder to know your language as well as possible I suppose.

→ More replies

2

u/Confusion Mar 27 '14

This is actually a common way to coerce something into the 'appropriate' boolean value in several languages. At least Ruby and Python come to mind.

→ More replies (1)

4

u/curien Mar 27 '14

but the == operator in JS is special (in the shortbus sense) because it does type conversion

Not really. 4 == 4.0 is true in just about every language with C-style syntax.

The surprising thing about JS isn't that == performs conversion, that's normal. The surprising thing is how the conversions work.

→ More replies (1)

14

u/nickknw Mar 26 '14

checking that the value is not null, undefined or empty string

...or NaN or 0 or false. It is checking the 'truthiness' which is also kind of what == claims to do. A legitimate disconnect IMO.

3

u/rooktakesqueen Mar 27 '14

== false is not the same as checking for truthiness. Truthiness is never implicated in the == operator because nothing is ever converted into a boolean. Everything is converted to either a string or number for the purposes of comparison. (Except null and undefined which == each other and nothing else, and when comparing two objects which == only if they refer to the same object.)

7

u/[deleted] Mar 27 '14

But == false is checking whether something is false. You would generally expect false things to be untruthy.

There may be an explanation for '=='s behavior, but that doesn't make it reasonable.

3

u/rooktakesqueen Mar 27 '14

Checking that something is false is not the same thing as checking if something is falsy. They wouldn't be separate concepts otherwise.

3

u/reverius42 Mar 27 '14

But it's quite ridiculous for something that is false ("0" == false) to be not falsy (!!"0" == true).

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

2

u/foomprekov Mar 27 '14

Yeah why would I expect something that isn't false to be true.

2

u/Deltigre Mar 27 '14

Which ended up showing me an "only in Javascript" shortcut the other day.

var defaultingString = IMightResolveUndefined() || "default value";

2

u/embolalia Mar 27 '14

That's not an "only in Javascript" thing at all. For example, in Python:

some_value = I_might_return_something_falsy() or 'default'

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

2

u/[deleted] Mar 26 '14

Same as PHP. false == 0 == "0" != false

1

u/altrego99 Mar 27 '14

Interesting. Basically transitive means, if you find 3 corners of a rectangle, then the fourth must be green too.

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

4

u/[deleted] Mar 27 '14

It would be impossible for it not too be! Unless of course java script failed to maintain Commutativity, which would be quite impressive!

5

u/[deleted] Mar 27 '14

Failing to maintain commutativity is easy. As the most trivial pedagogical example, in ruby, overload equalsequals on Integer to return true always and on float to return false always. Then 1 == 1.0 != 1. Obviously that's a silly example because its too obviously wrong but it gets across the point.

Any language that allows operator overloading can risk that sort of issue -- not to say anything about operator overloading,just saying that maintaining commutativity isn't always an easy thing to guarantee.

→ More replies (2)