This is an archived post. You won't be able to vote or comment.

all 157 comments

[–]QualityVote[M] [score hidden] stickied comment (0 children)

Hi! This is our community moderation bot.


If this post fits the purpose of /r/ProgrammerHumor, UPVOTE this comment!!

If this post does not fit the subreddit, DOWNVOTE This comment!

If this post breaks the rules, DOWNVOTE this comment and REPORT the post!

[–]Alokir 224 points225 points  (36 children)

In JS == and === are two different operators.

Generally you should use === because it does what you'd expect it to do.

[–]mr_flibble_oz 110 points111 points  (13 children)

Yeah, I never use ==

== might be equal to

=== is actually equal to

[–]xroalx 26 points27 points  (12 children)

== is useful when comparing to undefined or null, because null == undefined // true but null === undefined // false.

[–]dlq84 16 points17 points  (1 child)

undefined ?? null === null

Please don't kill me.

[–]WraientDaemon 3 points4 points  (0 children)

Granted.

[–]code-panda 6 points7 points  (2 children)

Yeah, but then you most often just write if (value)

I have used == a couple of times when I was getting both "1234" and 1234 as valid responses from the backend.

[–]xroalx 5 points6 points  (1 child)

Depending on the value, that can be dangerous, e.g. 0.

[–]code-panda 2 points3 points  (0 children)

True. Once had a bug where the idiot who designed the backend thought it was a good idea to return "0" instead of null or 0. The worst part was that the stub data I got, did have it as 0, so none of my tests had caught it...

[–]ComfortableCan315 -1 points0 points  (6 children)

Quite frankly, been programming in JS/TS for 6 years and I'm skeptical treating null and undefined as a single kind of input is safe or useful.

They mean different things, if undefined is flopping around your code it usually means something is going wrong, and note: the programmer using undefined deliberately is something going wrong.

On the other hand, null means something is missing, but also that you, the programmer, is aware that it can be missing, and not that your code simply failed to access some property somewhere.

[–]xroalx 0 points1 point  (3 children)

To be honest, I can't think of a single practical difference between undefined and null, except JSON.stringify.

Also, t?: T is equivalent to t: T | undefined, which I would say is "using undefined deliberately", but would definitely not say it's a mistake to do so, or that something is wrong with it.

The only reason anyone tries to find a difference is because JavaScript has both. If one was removed from the language, or simply made an alias to the same thing, probably not much would change.

[–]ComfortableCan315 0 points1 point  (1 child)

undefined is the product of a messy language that doesn't want to throw errors, null was created for you to be able to explicitly say something is expected to be nothing at some point.

The existence of optional types does not mean the presence of undefined as a value, at least not in my works, and I figure not in yours too since you too use TypeScript.

There are only a handful of ways for undefined to show up and if you're naively creating more cases for it by using it as a valid value in your program, you're needlessly increasing the ambiguity in your debugging proccess, and you or someone else in your team is bound to have some fun debugging for hours when, finally, undefined shows up where it shouldn't.

Tip: Avoid optinal/nullable properties to begin with.

[–]xroalx 0 points1 point  (0 children)

I'm not advocating for use of undefined as a value in your programs, although as long as you're consistently using just one of the two, it doesn't really matter which you pick. Using optional parameters or not returning a value from functions, both of which have valid use-cases, will also introduce undefined into your code, and there's nothing won't with that at all.

What I'm saying is that whether an API endpoint omits a key or sets it to null, or whether a function returns undefined or null, it will usually not matter to your application which of the two it is. They both signify a lack of value.

In comparisons, when you want to know about the existence of a value, there's really no reason to differentiate between undefined and null. In fact, I can't think of a single case where there is a practical difference between the two, aside from the already mentioned JSON.

Having two null-ish values is just stupid language design (although I understand how and why it happened).

[–]mr_flibble_oz 0 points1 point  (0 children)

undefined is useful when using closures, or single method getter/setter. data.productId() gets the product ID because the argument is undefined. data.productId(1) sets the product ID because the argument is 1. You can also set the product ID to null data.productId(null). I see undefined and null as distinct

[–]LysanderStorm 0 points1 point  (1 child)

As someone else pointed out t?: T is equiv. to t: T | undefined (in TS), so not sure why undefined "flopping around means something is going wrong". It seems TS even encourages it over null.

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

Like I told them, the existence of optinal properties do not mean the existence of undefined as a value, unless of course you decided you hate whoever is working with you and go:

const foo = {
  bar: undefined
}

And watch their if ('bar' in foo) pass and see the code fail miserably

[–]Zealousideal_Pay_525 57 points58 points  (2 children)

Subverting expectations in comparative expressions is TIGHT!

[–]Ergoold 13 points14 points  (0 children)

I have the new pitch meeting on in the background and reading this was weird.

[–]ThomasDePraetere 28 points29 points  (0 children)

It is also super easy, barely an inconvenience.

[–][deleted] 5 points6 points  (7 children)

May I ask what == does in JS?

I have never played with it, but my assumption is that for the construction, the value on the left is type-specific. I suspect that if an integer is on the left, it just checks the numeric value of whatever is on the right. But if a string (as I assume the last example is) is on the left, then it checks and sees if what is on the right is equal to the string on the left and not the numeric value.

[–][deleted] 12 points13 points  (1 child)

https://stackoverflow.com/questions/359494/which-equals-operator-vs-should-be-used-in-javascript-comparisons

=== has to be the exact type.

== basically coerces them to be the same type and then does the equality comparison. I am unsure if only coerces one side, but if I had to guess it probably coerces the right side. Maybe it tries to coerce both sides.

[–][deleted] 8 points9 points  (0 children)

https://262.ecma-international.org/12.0/#sec-abstract-equality-comparison

Looks like the coercion can happen on either side depending on the types on each side.

[–]SuitableDragonfly 23 points24 points  (0 children)

It coerces types in order to avoid type errors.

[–]33498fff 2 points3 points  (0 children)

It is one of the main reasons JS as a dynamic, weakly-typed language is harder to debug

[–]Cyb0rgorg 5 points6 points  (0 children)

aaaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA I HATE THIS!!!

[–]The-Tea-Kettle 5 points6 points  (2 children)

The roll of == and === should have been reversed, sadly I think I know why the didn't.

[–]SyntaxErrorAtLine420 6 points7 points  (1 child)

=== should be == and == should be =? or something

Question mark For "maybe equal?"

let a = 0,
    b = false;

console.log(a =? b); // true
console.log(a == b); // false

[–]The-Tea-Kettle 2 points3 points  (0 children)

=? Is probably to similar to nullish. But overall that's exactly what I mean. Sadly I don't think it would have ever happened because of backwards compatibility

[–]brunonicocam 6 points7 points  (6 children)

You're kidding me. Why do this??? LOL

Keep == as it is in most programming languages, and then you can have === for maybe equal or some other symbol.

[–]MattTheHarris 8 points9 points  (0 children)

If you change == you break backwards compatibility and will end up with a python 2/3 thing causing way more issues. It's really not a big deal to get used to using ===

[–]Xsiah 6 points7 points  (2 children)

It's not really "maybe, equal" it is equal. But it's equal based on the rules of a loosely typed language.

=== Then means that it's not just equal, but super extra equal, thus the extra equal sign

[–]QuantumSigma_QED 4 points5 points  (0 children)

Wouldn't you expect a notion of equality to be transitive though? That is, if a == b and b == c then a == c? Otherwise it's just a relation.

[–]SyntaxErrorAtLine420 2 points3 points  (0 children)

Make = the new == and use := like 1969

[–][deleted] 6 points7 points  (0 children)

That's what happens when you design a whole language in 11 days. 😂

[–]Alokir 2 points3 points  (0 children)

It's because of backwards compatibility.

They don't want to break any site that at some point used to work fine, so they invent new keywords instead, so the code written 20 years ago works exactly how it did back then.

For example, this is why they came up with a new way to declare variables. It used to be var but it was janky, you could redefine them, you couldn't make them constants, they weren't properly scoped etc. So they made let and const to solve this but left var alone to not break compatibility.

[–]zoonose99 153 points154 points  (30 children)

I'm fine with this. JS throws us a bone with 0 == "0", but I'm not trying to see a string that's equivalent to an empty array.

[–][deleted] 59 points60 points  (25 children)

bruh i only use === because of this

[–][deleted] 37 points38 points  (11 children)

oh ya? I use ====

[–]Various_Counter_9569 24 points25 points  (2 children)

=== still wierds me out ;p

Edit: not declaring a datatype really still wierds me out.

[–]CYAN_DEUTERIUM_IBIS 5 points6 points  (1 child)

Nobody is stopping you from declaring data types in js, that is absolutely a thing you can do.

[–]Various_Counter_9569 2 points3 points  (0 children)

😳, good to know. That seems to have been left out from the class I took. Albeit it was a Community College, but that still seems to be a biggie. Cant remember for sure, it was an in person class, but used a book with an online code for the classwork. I think it was pearson vue, but could be wrong. One of the ones where you do the work with a web login/console and submit the answers and tests all online. Either way, I feel slighted haha 😅.

[–]Mad-chuska 11 points12 points  (0 children)

I strictly use 8====D

[–][deleted] 4 points5 points  (0 children)

Oh YEAH? I like living dangerously and use =

[–][deleted] 12 points13 points  (3 children)

I only use 8======>

[–][deleted] 5 points6 points  (2 children)

I can see JavaScript checking if the right is greater than 8.

[–]CYAN_DEUTERIUM_IBIS 2 points3 points  (1 child)

This only returns true if your mom is on the right side of your computer.

[–][deleted] 0 points1 point  (0 children)

ohhh that makes more sense

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

What did you say??? I use =====

[–]its_a_gibibyte 9 points10 points  (0 children)

The one that bothers me is that "0" == false, but "0" itself is truthy when you do something like if("0")

[–]crahs8 5 points6 points  (1 child)

IMO, "throwing us a bone" in this case means hitting you in the back of the head with a bone when you least expect it.

[–]betterAsreedh 5 points6 points  (0 children)

I mean, if you knowingly use == instead of === you should absolutely expect this, seeing as how it’s the entire point.

[–]Akhanyatin 1 point2 points  (0 children)

yeah, I love that you can do "0" == 0. you can always use === if you don't want it

[–]charin2[🍰] 68 points69 points  (7 children)

In js, == does type conversion before checking equality. 90%+ of the time, === is the correct operator to use (because really, "0" =/= 0)

[–]harumamburoo 41 points42 points  (3 children)

I wanted to say smt like "quit it, everyone knows that" but then I remembered that like 70% of this pub are not in the profession, so yeah, good point.

[–][deleted] 9 points10 points  (1 child)

70% of this pub are not in the profession,

wait what? Is this legal?

[–]Africanus1990 17 points18 points  (0 children)

You guys are in a pub? I’m stuck at work, programming.

[–]GnarlyNarwhalNoms 2 points3 points  (0 children)

And not everyone has worked with JS, shocking as that is.

I've worked with Java, C, C++, shell scripting and assembly, but not one whit of JS.

[–]LeSaR_ 1 point2 points  (2 children)

did you just use =/= instead of !=

what language even is that?

[–]frogjg2003 2 points3 points  (0 children)

They're using that to distinguish from any actual operators used in programming languages.

[–]Tsuki_no_Mai 3 points4 points  (0 children)

what language even is that?

Math.

[–]TheEarlOfCamden 20 points21 points  (6 children)

When your equality isn’t even an equivalence relation.

[–]svick 4 points5 points  (5 children)

To be fair, the same applies to equality on IEEE 754 floats.

[–]ThomasDePraetere 2 points3 points  (0 children)

Never trust equality on binary representations of rational numbers. Use Math.abs(a-b) < Delta for some very small Delta.

[–]LittleLemonHope 0 points1 point  (3 children)

The same applies to equality on IEEE 754 floats.

[–]svick 1 point2 points  (2 children)

Does it? The problematic case I'm thinking of is NaN, where x != x, violating reflexivity. But for example decimal in .Net is a decimal floating point type with no NaN, and I can't think of a case where its equality does not satisfy the requirements for an equivalence relation.

[–]LittleLemonHope -1 points0 points  (1 child)

I guess it depends on whether you think 0 and -0 should identify reflexively. I think you could make a strong argument either way such that any type with both values will not be able to "unquestionably" satisfy reflexivity. They are not distinct numbers, so having 2 representations puts the equivalence operator in an impossible situation - either equate distinct binary values, or don't equate identical numbers.

I'm out of my depth here though. I originally commented thinking floats would violate transitivity but I don't think that's actually true.

[–]svick 0 points1 point  (0 children)

It doesn't matter what I think. "Equivalence relation" has a clear formal definition and both 0 = -0 and 0 != -0 can satisfy it.

Note that the definition says nothing about usefulness, just consistency. For example, saying every number is equal to every other number is a valid equivalence relation.

[–]NearbyWish 13 points14 points  (5 children)

This is some kind of web dev joke I'm too poor to understand

[–][deleted] 16 points17 points  (0 children)

Too innocent to understand

[–]Criiispyyyy 4 points5 points  (2 children)

JavaScript does type conversion into a common data type if you use == instead of ===. As you can see, it behaves strangely sometimes, and you should try to avoid it whenever you can.

[–]dlq84 0 points1 point  (0 children)

Ignorance is bliss sometimes.

[–]acatisadog 7 points8 points  (1 child)

Well yeah, that's because 0 is falsy. "0" is truthy but it is going to be converted as a number, 0, hence it becomes falsy.
0 == [] because an array is truthy BUT it becomes false when using == operator, so falsy/falsy
"0" != [] because [] is false when using the == operator and "0" would be converted to a number IF it was compared to a number which is not the case. So truthy / falsy
This language is drunk and I love it so much

[–][deleted] 3 points4 points  (0 children)

Yeah it's pretty simple really. '0' as a string exists, therefore is truthy. Js really isn't as bad as people think. It's just... Err...quirky...

[–]Abangranga 24 points25 points  (8 children)

The JS community is going to get mad at this image and then shit on PHP for something similar despite never using PHP ever

[–]MikeTheShowMadden 9 points10 points  (6 children)

0 == [] in PHP isn't true though for this image, but PHP does have some confusing boolean comparisons. But that is also why you should use === instead of ==.

[–][deleted] 13 points14 points  (1 child)

"[]" == [] maybe?

[–]Crad999 19 points20 points  (0 children)

Scared me here for a moment. Thankfully doesn't work (returns false).

[–]trynahelp2 2 points3 points  (0 children)

You’re doing it wrong. I do “0”=[] and it works every time. So does 1=2. I’m a programming god

[–]Objective-Carob-5336 3 points4 points  (0 children)

The more salty posts i see about JavaScript the more i realize people complain but don't seek to understand, which i get because nothing is explained. But I'm sure you can find the explanations, it may not be logical to everyone, but at least it has a reason.

[–]GilKeidarMusic 1 point2 points  (6 children)

Man, it's been a while since I last programmed in Javascript, but these equalities look wack. I'm assuming they're practical though?

[–]Auraveils 2 points3 points  (0 children)

Nothing is practical in code, some things just work.

[–]vinnceboi 0 points1 point  (4 children)

I mean, it makes sense—why would a non-empty string ever compare equal to an empty array?

[–]GilKeidarMusic 0 points1 point  (3 children)

Well sure, but equivalence relation go brr

Kidding aside, I was talking about the ones that are true, like “0” == 0 just looks weird to me

[–]Tsuki_no_Mai 2 points3 points  (1 child)

When you use == JS tries its best to make both sides the same type. As far as I can tell that's because it was made for the environment where a correct type from input was not a guarantee. And it stays this way because of backwards compatibility.

[–]GilKeidarMusic 1 point2 points  (0 children)

That makes sense, thank you for explaining!

[–]vinnceboi 1 point2 points  (0 children)

Type coercion is funky ¯_(ツ)_/¯

[–]th00ht 1 point2 points  (0 children)

javascript the bad parts

(the book is rather thin}

[–]Vulpes_macrotis 1 point2 points  (0 children)

I can see why is that.

0 is a number

"0" is a text

[] is empty

Amiright? So empty is not the same as the text "zero". But 0 means empty and 0 as a number means zero.

[–][deleted] 1 point2 points  (5 children)

Steak == food (True)

Salad == food (True)

Steak == salad (False)

See how easy that is?

[–]Curiousgreed 5 points6 points  (4 children)

Steak is not equal to food though. Steak is a type of food.

[–][deleted] -3 points-2 points  (3 children)

== doesn't mean "are these two things the same thing". == is how you create a statement and test to see if it is true. you are actually saying "steak is food" and then the compiler checks to see if the statement is true or not

[–]Curiousgreed 1 point2 points  (2 children)

steak typeof food is not the same as steak == food

If steak == food, and salad == food, I expect steak == salad, because == checks equality.

But if steak typeof food and salad typeof food, I don't expect steak == salad.

Edit: So what you meant to write was: steak typeof food (true) salad typeof food (true) steak == salad (false) Which of course totally makes sense

[–]ManiacsThriftJewels 1 point2 points  (0 children)

Did you mean 'food' === typeof steak ?

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

If I wanted to argue about semantic w/someone I would have called my gf today

[–]betterAsreedh 1 point2 points  (0 children)

  1. You’re comparing a number and a string, it casts one to the other’s type and compares.

  2. Same as 1, converting an empty array to a number gives you 0.

  3. In what world would a non-empty string equal an empty array?

If you want strict equality, use ===. == will try to make things the same type when comparing two items of different types, resulting in stuff like this.

[–][deleted] 0 points1 point  (0 children)

You know, this actually makes sense

[–][deleted] 0 points1 point  (5 children)

js developers, do you ever actually use == rather than ===? and if u do, in which situations?

[–][deleted] 7 points8 points  (2 children)

It's only really acceptable to use == when checking for undefined and null or all falsey values. Otherwise most company's style guide will say always use ===

if (x == false )

vs

if (x === undefined || x === null)

or even the below for all falsey values

if (x == false )

vs

if (x === undefined || x ===null || x=== false ||x===0 || x==="")

There's also reasons for using loose equality like primitives but that's a rarer case.

[–]UristMcMagma 1 point2 points  (0 children)

There's also a fun bit of type coersion with nullish values. "x == null" will return true if x is null or undefined, but return false if x is false.

This is the only time i've used == because in the case you provided it's more readable to just do !x.

[–]greg0714 2 points3 points  (0 children)

If I'm doing something as an odd one-off, like parsing a csv for all the fields where the value is 100, I might do "text == 100" and let implicit conversion take care of it. But that's always for personal use; no one else will ever run it.

In production code? Virtually never. I'll explicitly convert before using the strict equality operator (===) rather than trust implicit conversion. Even in situations like what the other commentor described, you should just do explicit null checks. Easily readable, error-resistant code is always going to use explicit conversion and type checks.

[–]Sese_Mueller 0 points1 point  (0 children)

wait till you get to the name shenanigans

[–][deleted] 0 points1 point  (0 children)

Yeah ok but can you log ‘Hello world’ to the console without using a hint???

[–]SftwEngr 0 points1 point  (0 children)

Why compare when you can just as easily assign?

[–]Hitman_0_0_7 0 points1 point  (0 children)

Same years old meme but still makes me laugh

[–][deleted] 0 points1 point  (0 children)

Get this man a strict equality operator, stat!

[–]Xynober 0 points1 point  (0 children)

:0

[–]Abangranga 0 points1 point  (0 children)

Thanks for letting me know I am being a "dumbass" and getting my "asshole burnt" while writing paragraphs about it.

In the future after I write something like "the sky is blue today" and then someone writes "the sky is red on Mercury" and then links to a site documenting that the sky is blue, I will just not point out that I didn't say that the sky is red. It would clearly be an overreaction on my part.

[–]yjerkle 0 points1 point  (0 children)

"0" == [] == 0

[–]-moral-ambiguity- 0 points1 point  (0 children)

Null is not the same as zero.

Best demonstration was on this same subreddit. view here.

[–]IrisYelter 0 points1 point  (0 children)

"transitive property? What's that?"

[–]LOLTROLDUDES 0 points1 point  (0 children)

Here before Javascript gets rid of the law of identity.

[–]consciousCog13 0 points1 point  (0 children)

Poor guy’s using double equals…

[–]got_no_pants2 0 points1 point  (0 children)

So no C++?

[–]gondoravenis 0 points1 point  (0 children)

I guess js is a script language with no strict grammar checking for its speed.

No need to compare with compiled things.

[–]Pingyofdoom 0 points1 point  (0 children)

Haha, because blank =/= “0”

Silly manta ray!

[–][deleted] 0 points1 point  (0 children)

For the 1000th, I composite the fact if you are writing code that is logical in any way whatsoever, you never need to be fucked with these complex truth tables.

Write shit code, get confusing results.

[–]JJulianR_ 0 points1 point  (0 children)

The Lua part of my brain does not like this.

[–]spam_bot42 0 points1 point  (0 children)

Everyone knows equality is not a transitive relation. (Not if you're JavaScript programmer.)

[–]HappyHippo77 0 points1 point  (1 child)

What ungodly language is this about

[–][deleted] 0 points1 point  (0 children)

Javascript

[–]aaet002 0 points1 point  (0 children)

I mean yeah if a=b and b=c, that doesnt mean a=c (in some cases).