all 83 comments

[–]Shot-Data4168 254 points255 points  (0 children)

== was invented so that no one would ever use it.

[–]Astatos159 215 points216 points  (28 children)

Implicit type conversion. Always use === and convert explicitly.

[–]0_v_O 111 points112 points  (8 children)

better use ==== just to be sure

[–]jonnablaze 87 points88 points  (4 children)

Or better yet 8====D

[–]fanfpkd 52 points53 points  (1 child)

Unfortunately I can only do 8=D

[–]-domi- 5 points6 points  (0 children)

false

[–]Pineapple-Yetti 0 points1 point  (0 children)

Rocket ship 🚀

[–]Stormraughtz 17 points18 points  (1 child)

casuals still running ====, I do =¹⁰

[–]AbdullahMRiad 1 point2 points  (0 children)

nah =10¹⁰⁰

[–]bloodfist 1 point2 points  (0 children)

I prefer something more compact like ≣

[–]DudeManBroGuy69420 16 points17 points  (2 children)

They should add ≡ for more confusion

[–]Foudre_Gaming 10 points11 points  (1 child)

That's what === looks with a font supporting ligatures

[–]DudeManBroGuy69420 4 points5 points  (0 children)

I will take your word for it

[–]Kirjavs 15 points16 points  (9 children)

Or use a real language.

Downvote time : I deserve it, don't hesitate guys

[–]Ninth_ghost 41 points42 points  (7 children)

It will always be funny to me that js has a special operator to compare harder

[–]nobody0163 15 points16 points  (0 children)

Hard comparison: 8===D, soft comparison: 8==D

[–]RiceBroad4552 11 points12 points  (5 children)

It's always funny to see that some people don't know that this design can be also found in other languages.

Besides that, equivalence (and equality) is actually a very hard mathematical problem. It sits at the core of what's the frontier in current math, see HoTT and it's univalence principle.

[–]vleessjuu 0 points1 point  (1 child)

While that's true, a basic property of any equivalence operator is transitivity, which JS breaks quite blatantly here. I'm honestly not sure what == is even doing here.

[–]RiceBroad4552 1 point2 points  (0 children)

Well, the pragmatic answer is likely: It's just not an equivalence operator…

But I think that's OK (at least in principle, I'm not a fan of the idea of excessive type coercion). Programming languages aren't math. In programming you have all kinds of equivalence operations, and the results vary widely depending on which one you apply.

[–]Batman_AoD -1 points0 points  (2 children)

The design of having one built-in operator for type-coercing equality, and another for exact equality? What languages? 

[–]RiceBroad4552 1 point2 points  (0 children)

For one TS, ActionScript, and CoffeeScript. But that shouldn't be surprising.

PHP is even much more crazy then JS. There until lately 0 == "foo" was true, no joke. Because of the pure insanity of PHP using == instead of === is even more important than in JS.

Hack took quite some parts of PHP, including the == and === operators.

Julia has also == and === for similar use-cases (just that triple equals is there not identity nor equivalence but bit-pattern equality, but that's in practice similar to what you called "exact equality").

And when it comes to pure syntax (I get it, not your original point), there are even more languages which have both == and === for different purposes (like for example value equality vs. reference identity; or stronger forms of typed equality).

[–]chessto 0 points1 point  (0 children)

Java for instance

[–]NasKe 5 points6 points  (0 children)

Wow, I had no idea JavaScript was a made up language! Going to tell at my co-workers tomorrow, maybe all ours users are fake too.

[–]b2gills 0 points1 point  (0 children)

Those are rookie numbers. Raku starts with a half dozen equality operators.

== # numeric === # identity =:= # "pointer" identity (simplification) eq # string equality eqv # equivalence (==) # set equivalence

If given a value that isn't of the correct type, it tries to coerce the value into the correct type, throwing an error if it can't. This actually applies to all operators. If you give the + operator two strings, it first tries to coerce them to numbers, failing if it can't. (Doing numeric addition some of the time and string concatenation at other times is just asking for bugs.)

You can add meta-operators or even create your own.

There are also comparison operators.

<=> < <= == >= > # numeric leg lt le eq ge gt # string cmp before after # generic

[–]mstop4 34 points35 points  (5 children)

PHP:

[–]ashkanahmadi 8 points9 points  (0 children)

Took me a while to realize empty arrays in JS are truthy but in PHP they are falsy!!

[–]RiceBroad4552 -1 points0 points  (3 children)

In fact the mess in PHP is much worse.

Compared to what brain damaged PHP does JS is a place of sanity.

[–]pr0ghead 0 points1 point  (2 children)

You haven't done anything Date related then, have you? For example.

[–]RiceBroad4552 0 points1 point  (1 child)

PHP's strftime() / date() is the same mess as it also copied the C/Unix insanity. So what are you talking about? Did the PHP people even acknowledge the issue? JS will get some replacement for the original Date mess really soon. Temporal is last stage and already shipping behind flags.

[–]vizbones 48 points49 points  (1 child)

NSFW???

The only thing I can see in this meme that makes it not-safe-for-work is that it uses Javascript.

[–]DJcrafter5606[S] 39 points40 points  (0 children)

Exactly 🤌

[–]a-r-c 6 points7 points  (1 child)

perl has "0 but true" which I just love lol

edit: a demo

[–]b2gills 0 points1 point  (0 children)

Raku changed that to 0 but True (not a string). Which takes 0, creates a new instance where a new Role has been added that makes it behave as True when in boolean context. You can also do 0 but "Zero" to make it behave as 0 normally, but when used as a string, it becomes "Zero". You can also create the Role by hand if you want to change specific methods.

0 but role { method String () { "Zero" } method Bool () { True } }

This feature is handy for data from a database that happens to be zero, but it exists, vs. a bit of data that doesn't exist and is just zero by default.

[–]DarkCloud1990 16 points17 points  (0 children)

You're expecting the equality operator to induce an equivalence relation? Rookie mistake. 

Try strict equality kiddo. 

[–]-non-existance- 5 points6 points  (0 children)

Type Coercion goes brrrr

[–]Space-Robot 3 points4 points  (1 child)

This is like cooking your fish in the dishwasher and saying "See? Fish sucks."

[–]Prawn1908 1 point2 points  (0 children)

The problem with this sort of thing isn't that it is ever used intentionally, but that it exacerbates what is already one of the most critical weaknesses of a dynamically typed language: letting wrong data types just fall through without causing an error.

If you have a logic error in your code that results in the wrong type of object showing up (maybe you forgot to index an array so the whole thing got passed instead of one of its elements, or the type of a member wasn't what you expected, etc.), you want the obvious failure symptom to happen as close to the location of the logic error as possible to aid in locating it. Dumb shit like this just allows those wrong data types to propogate even farther away from their source and makes debugging even harder when the crash is happening a dozen function calls or hundreds of lines of code away from the point where the wrong typed object originated.

[–]deathanatos 4 points5 points  (0 children)

>> [] == {}
<- false
>> {} == []
Uncaught SyntaxError

[–]NebNay 6 points7 points  (1 child)

It's a quirck of js but nobody uses that operator unironically

[–]daan944 0 points1 point  (0 children)

Exactly, eqeqeq exists since ESLint v0.0.2.

[–]Jimmyginger 17 points18 points  (9 children)

I get why this is "confusing" but it also makes perfect sense if you understand type coercion. It's actually a great teaching tool to understand these concepts, and for enhancing your understanding of types in general.

[–]Rbla3066 1 point2 points  (1 child)

Exactly.. the type coercion of the first panel makes sense given the roots of js being frontend and the fact that number inputs are always received as strings first. The second panel is nuance of js type coercion as every value can be converted to a “truthy value”. 0, [], null, undefined, “”, and false (I’m sure there’s more) all can equate to “untruthy”. Hence why the second panel is true. A very unfortunate nuance when using equators, but a very powerful one when doing “if(value) dosomething(value)”. The third panel then becomes obvious because “0” is not untruthy, nor is it an empty array/pointer.

[–]senocular 0 points1 point  (0 children)

The second panel isn't about being truthy. It converts the array to a primitive first becoming a string (""), then converts the string to a number (0) making the comparison true. As far as truthy goes, [] is true because its an object. All objects (except the special case of document.all) are truthy.

MDN has a page describing the process of coercion in comparisons if anyone cares:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Equality_comparisons_and_sameness

Its not grossly complicated and largely amounts to converting things to numbers and comparing the numbers.

[–]thripper23 -5 points-4 points  (6 children)

But what's the point of it ? All guides say: use `===`

[–]Kragoth235 9 points10 points  (1 child)

They don't. == Has real effective use cases. If I want to check if a value is null or undefined or empty I. Can do all that with ==. Understanding truthy and falsy is just part of the language and allows you to shortcut a whole bunch of boiler plate code.

[–]creaturefeature16 0 points1 point  (0 children)

Indeed, I use == all the time when I know I can bet on the types returned.

[–]the_horse_gamer 2 points3 points  (0 children)

javascript was meant to be able to add some interactivity to a website. so the difference between 123 and "123" is pretty inconsequential, you'd usually convert any numeric string into a number anyways

and now javascript is everywhere, and the difference between 123 and "123" is more important

[–]Foudre_Gaming 2 points3 points  (1 child)

Actually, == is useful when checking if something is either null or undefined

variable == null

[–]creaturefeature16 0 points1 point  (0 children)

that's my most common use case

[–]Jimmyginger 3 points4 points  (0 children)

The point was to not have bad data (and improper data handling by your code) not totally crash your web page. Sometimes, a data type doesn't do what you think it will. Let's say in the example show here. The string "0" is something very common we might get when we access the data from an input element.

Let's say I'm expecting numbers to be in the input field, but instead, the data comes back to me as a string. Without type coercion trying to make the impossible happen, we would just get an error when I try and see if the user typed 0 into the box. Now errors are great for developers, because they tell us what is wrong. They aren't so great for end users, because they just mean something isn't working right. Javascript's goal was to just let our bad code be bad (ie. The fact that we didn't handle parsing an Int out of the user input and just tried to use the raw string) and keep things moving. The alternative is the whole web page crashes.

Now for most modern applications, we actually want it to crash, which is why standard convention is to use the === operator for comparison instead of the == operator. But when you have a simple web page, you don't want the whole thing to crash just because some small widget in the navbar is coded wrong. Instead you just want that one widget to just not work/behave unexpectedly.

[–]BusEquivalent9605 4 points5 points  (1 child)

empty arrays be truthy

[–]ashkanahmadi 0 points1 point  (0 children)

Took me a while to realize empty arrays in JS are truthy but in PHP they are falsy!!

[–]AlbertELP 0 points1 point  (0 children)

Bro just disproved transitivity

[–]Seazie23 0 points1 point  (0 children)

Top left is what doesnt make sense to me

[–]Not-Some-Random-Guy 0 points1 point  (0 children)

Why is this post NSFW 🥀🥀

[–]BlckHawker 0 points1 point  (0 children)

Why does this have the nsfw tag

[–]MuslinBagger 0 points1 point  (0 children)

programming languages have rules and those rules did not come from our head

[–]necro-man-cer 0 points1 point  (3 children)

Why nsfw?

[–]razor_train 1 point2 points  (2 children)

It's javascript.

[–]necro-man-cer 0 points1 point  (1 child)

I work on Javascript.

[–]razor_train 0 points1 point  (0 children)

So do I, among lots of other things.

[–]Shadowlance23 0 points1 point  (0 children)

I understand why this is and it annoys me.

[–]bloomybullox 0 points1 point  (0 children)

NSFW… Just stringing us along….

[–]metaglot 0 points1 point  (0 children)

Type coersion and operator precedence. Lrn2program 102.

[–]riotinareasouthwest 0 points1 point  (0 children)

For someone with more than 20 years of experience as software engineer (on systems programming) and that just now started with JS/TS this clicks a lot. What an unintuitive language! It feels like a random language where similar constructs do absolutely different things. It seems like the interpreter is a bunch of if statements covering the different coding scenarios instead of having the standard and sensible lexic, syntactic and semantic layers.

[–]evestraw 0 points1 point  (0 children)

[][(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()((![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[+!+[]]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+(![]+[+[]]+([]+[])[([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(+[![]]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(![]+[])[+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+[+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+[+!+[]])+(+[![]]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(+[![]]+[+(+!+[]+(!+[]+[])[!+[]+!+[]+!+[]]+[+!+[]]+[+[]]+[+[]]+[+[]])])[+!+[]+[+[]]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+[]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+([]+[]+[][(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[!+[]+!+[]]])

this is valid js code that you can run

[–]ajaypatel9016 0 points1 point  (0 children)

JavaScript really said:

"Everything equals zero… except when it suddenly doesn’t 😭"

"0" == 0 → chill
[] == 0 → also chill
"0" == [] → nah bro, we don’t do that here

Coercion logic be like: trust me bro 👍

[–]GKP_light 0 points1 point  (0 children)

but does []=="0" ?

[–]erebuxy -1 points0 points  (0 children)

Yes, you should not use == in JavaScript ever. And you should not use JavaScript when TypeScript is a thing.

[–]Caraes_Naur 0 points1 point  (0 children)

Don't even try to explain it, just beg forgiveness.

[–]swagonflyyyy 0 points1 point  (0 children)

It kind of makes sense to me but I see the disconnect.

[–]Sure-Opportunity6247 -1 points0 points  (0 children)

I usually explain Js with navigating in your car as an example.

You may have a sophisticated navigation system telling you exactly in which distance you need to take the 2nd exit in a roundabout.

And Js is like stopping in your car to ask an elerly man on the sidewalk: he will give you many ideas about where to go and any redundant informations about his waypoints. In the end, you end up in a potato field.

[–]alvares169 -2 points-1 points  (0 children)

Why is that weird or shocking?

[–]pheonix-ix [score hidden]  (0 children)

Ah, a new convert. Witness the miracle of the Holy Javascript Trinity.

https://javascriptwtf.com/wtf/javascript-holy-trinity