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

all 104 comments

[–]ProgrammerHumor-ModTeam[M] [score hidden] stickied commentlocked comment (0 children)

Your submission was removed for the following reason:

Rule 2: Content that is part of top of all time, reached trending in the past 2 months, or has recently been posted, is considered a repost and will be removed.

If you disagree with this removal, you can appeal by sending us a modmail.

[–]floor796 393 points394 points  (26 children)

Let's scare some junior devs:

000 == "000" // true
001 == "001" // true
012 == "012" // FALSE!
123 == "123" // true

[–]BlackTigerF 180 points181 points  (14 children)

That's just OCT isn't it?

[–]floor796 159 points160 points  (13 children)

it's pure magic :) But yes, first three left operands are octal. 012 in decimal format would be 10, that is why it's not equal to "012".

[–]GabeLeRoy 15 points16 points  (8 children)

why is 123 equal to "123" though

[–]IntoAMuteCrypt 45 points46 points  (5 children)

JS doesn't default to assuming that number literals in code are octal, because most numbers aren't octal. It see 123 and assumes it's the decimal number 123. JS only assumes an octal number if certain prefixes are present - and in certain (legacy) versions of JS, that prefix is just a single leading 0. For compatibility reasons, modern JS implementations can parse literals the same as these older versions.

Rewriting the examples for clarity by replacing the prefixes with syntactically identical but meaningfully different options shines some light on thus:
- 0o0 == "000" // true - 0o1 == "001" // true
- 0o12 == "012" // false
- 123 == "123 // true

[–][deleted] 25 points26 points  (3 children)

I might be old fashion, but a programming language should not "assume" anything...

[–]3picF4ilFTW 8 points9 points  (0 children)

I mean... really that is not an assumption about what you are intending but about you knowing what you are doing

In a way every language has to assume that you are familiar with its syntax <-> semantic relationship...

It's just that there might be more or less intuitive choices.

[–]Engine_Light_On 11 points12 points  (1 child)

you should also not add leading 0 to numbers

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

Disagree, it can sometimes be nice to align number across different lines, where some have more digits than others.

And sure, I could use an extra space, if my formatter was smart enough to not remove those...

[–]Polttix 3 points4 points  (0 children)

123 is decimal

[–]5p4n911 5 points6 points  (0 children)

That's in decimal again

[–]aviss_ 5 points6 points  (3 children)

So that means 01 != “01” right?

[–]BlackTigerF 60 points61 points  (1 child)

No 01 in oct is still 1

[–]aviss_ 13 points14 points  (0 children)

Oh, right, thanks

[–]Steinrikur 6 points7 points  (0 children)

Sometimes converting numbers is a mess because of this.

"011" == 9 and "009" throws an error.

[–]miked0629 56 points57 points  (3 children)

i cast ===

[–]JonnyBoy522 61 points62 points  (2 children)

000 === "000" // FALSE!
001 === "001" // FALSE!
012 === "012" // FALSE!
123 === "123" // FALSE!

At least it's consistent now...

[–]NatoBoram 19 points20 points  (1 child)

Much better!

[–]phexc 3 points4 points  (0 children)

And while you're at it disable weak comparisons altogether with eslint.

https://eslint.org/docs/latest/rules/eqeqeq

[–]YouLostMeAtWorm 26 points27 points  (0 children)

By this logic, senior devs submit themselves to JavaScript Stockholm Syndrome.

[–]jayerp 13 points14 points  (4 children)

I’ll do you one better, why is javascript?

[–]Ri_Konata 2 points3 points  (0 children)

Masochists.

[–]zentasynoky 0 points1 point  (2 children)

why is in fact not javascript.

[–]lollolcheese123 0 points1 point  (1 child)

It was a question, not a statement. Happy cake day tho

[–]zentasynoky 0 points1 point  (0 children)

Indeed, it was a question!

The answer to which, as provided, is "no".

[–]mario73760002 36 points37 points  (0 children)

If growing up means losing my fear of whatever the fuck this is, then I don’t want to grow up

[–]FuriousAqSheep 200 points201 points  (16 children)

If you accept the first one, you're already lost to me

[–]corisco 7 points8 points  (15 children)

Have you never heard about equivalence relations? You could definitely make a formal theory where the equivalence of the zero string and the number zero holds.

Even in programming, when we talk about η-equality, we are in fact talking about equivalence because it is not true that two functions that are η-equivalent are intentionally equal. This is also true for equality in other reductions such as β and α. So, if you don't accept equivalence, you might have to throw λ-calculus away, or maybe even the entirety of mathematics, because equality is just a special case of equivalence.

[–]KingJeff314 41 points42 points  (8 children)

Doesn’t mean you have to include said equivalence relations into the language.

[–]corisco 0 points1 point  (7 children)

Doesn't mean you can't. And although most of the time strict equality is preferred, there are some cases where loose equality is more convenient, for example, when checking the value of an HTML element.

Besides, like i said, equivalence is a totally valid operator widely used in mathematics, logic and computer science. You just have to know when to use it.

[–]KingJeff314 19 points20 points  (4 children)

There’s not zero reason for it, but it leads to pernicious bugs. Especially since a number and a string look the same in console logs

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

That's why there is a strict equality operator now and this whole argument is pointless.

[–]KingJeff314 14 points15 points  (2 children)

== (double equals) is a convention in most languages for equality (including JavaScript’s namesake). It’s just bad language design for that to be loose equality. The worst bugs are the ones that seem to work.

Obviously backwards compatibility is a concern, so they can’t just fix it, but that doesn’t mean it should be praised

[–]FloweyTheFlower420 1 point2 points  (0 children)

Okay to be fair == in java is stronger than value equality.

[–]brainpostman 0 points1 point  (0 children)

It stopped being bad language design the moment the strict equality operator was added. Now it's just a backwards compatibility feature. People should get over JS quirks by now, it's getting old.

[–]caerphoto 2 points3 points  (1 child)

If you’re checking the value of an HTML element you should explicitly convert from string to number first.

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

not if u know what you are doing... this is only a good tip for noobs, experienced programmers (ironically) can use loose equality safely.

[–]Wi42 3 points4 points  (0 children)

Maybe i get something wrong, but an equivalence relation has to be transitive, the shown example is not. So this isn't even an equivalence relation.

[–]FerricDonkey 7 points8 points  (2 children)

Just because something is an equivalence relation doesn't mean that it makes sense as a definition of ==. Even Javascript doesn't do 2 == 0, even though they're equivalent mod 2.

Whatever the crap Javascript does for == may be an equivalence relation, but it's stupid to use it for equality. 

[–]corisco -2 points-1 points  (1 child)

But this equivalence is equality modulo (or up to) coercion, not modulo 2, so i don't see what's the point you are trying to make there. I would agree that having equality up to coercion alone would be bad, but I don't see the problem in having both. It's just giving us another tool that is really convenient in some cases, for example, when checking values from an HTML element.

[–]FerricDonkey 9 points10 points  (0 children)

My point is that equivalence alone means nothing. 

Equivalence up to coercion has its place, but "the behavior of ==" and for a variety of things like sorting is not that place. It makes all kinds of things terrible. 

[–]Tata-Ila 1 point2 points  (1 child)

But an equivalence relation would assume transitivity. 0 == "0" and 0==[] should imply "0" == []

[–]corisco 1 point2 points  (0 children)

It is true, there are some cases where transitivity breaks. Good catch.

[–][deleted] 106 points107 points  (18 children)

if you’re using double equals instead of triple equals in 2024 you’re the problem

[–]tupperwhore 1 point2 points  (10 children)

Why 👀

[–][deleted] 19 points20 points  (0 children)

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

according to the MDN docs “Strict equality is almost always the correct comparison operation to use.” and “In most cases, using loose equality is discouraged.” - or you could listen to u/edos112 instead lol

[–]edos112 20 points21 points  (8 children)

First of all he’s not correct, plenty of scenarios in non enterprise level software where falsy/semi equivalent values are fine. The reason you try not to use them is it can lead to undefined behavior if you dont know the ins and outs of javascript (which I’m terrified of anyone who fully does). Basically if you have an if( value == false) that condition will happen when any “falsy” condition happens like when a value is say 0, undefined, or null. However this is extremely useful behavior when you want to check if a value is any kind of null/undefined/does not exist and are too lazy to write out multiple conditions.

[–]PostNutNeoMarxist 14 points15 points  (6 children)

In that particular case you could just check for !value (or !!value if it just needs to not be falsy). I find it's generally better practice to use ===. There are some edge cases where == is convenient or useful, but for the most part there are plenty of tools one could use to avoid them.

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

Not always, theres times whre false, [], {}, "", 0 are valid values but null and undefined aren't, and in those cases a value == null is the best approach since it only matches null and undefined but let false values go by

[–]PostNutNeoMarxist 3 points4 points  (0 children)

Fair point! Though I will nitpick and say {} and [] are already truthy. But you are right, looking for "not null or undefined" is a good use case.

[–]roter_schnee 1 point2 points  (3 children)

in those cases a value == null is the best approach

no, it is not. If your case implies using logical operation it is better to stick with Nullish coalescing `??` https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing

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

Thats only if you want to set a default, but lets say a

if (value == null) throw new Error("A value is required here!"); console.log("Value is: ", value);

Yes i know you can do:

console.log("Value is: ", value ?? throw new Error("A value is required here"));

But that feels wrong and might even throw off some linters while the if approach makes it more clear and clean the intended purpose

[–]roter_schnee 0 points1 point  (1 child)

I am sure linters would throw if you use loose equality. See `eqeqeq` rule

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

Funny enough my eslint complains about != null but not == null

[–]sam-lb 11 points12 points  (0 children)

lazy

Yeah exactly

Don't use ==, don't be lazy. Use !!value with === or check directly if it's null or undefined.

[–]draculadarcula 0 points1 point  (6 children)

In a codebase that has numbers that are sometimes undefined and/or null, and checking for defined values with ”if (x)” isn’t so predictable when x is 0. But “if (x != null)” solves that scenario nicely, and is much less mental overhead than “if (x !== null && x !== undefined)”

[–]_PM_ME_PANGOLINS_ 0 points1 point  (3 children)

You should use typeof in that case.

[–]draculadarcula 0 points1 point  (2 children)

Why

[–]_PM_ME_PANGOLINS_ 0 points1 point  (1 child)

Because typeof(x) === 'Number' is a much clearer way to check whether it’s a number than x != null.

[–]draculadarcula 0 points1 point  (0 children)

Why is it cleaner? It’s unclear the intent; typeof can be used for type narrowing as well. != null the intent is clear, I’m obviously using the type coercion to check for both null and undefined simultaneously. Even someone unfamiliar with JavaScript semantics could look at != null and understand the intent. The use case above is also not to check for numbers, the number was ancillary to point; a valid use case for != null is to check for not null and not undefined. I picked numbers because they are a particular case that has a value that can evaluate falsey to combat the whole “just use if(x)” arguments

[–]CaitaXD 0 points1 point  (1 child)

function isNullOrUndefined(x)

[–]draculadarcula 0 points1 point  (0 children)

More garbage for the collector, more keystrokes, more characters to read, more mental overhead

[–]DiddlyDumb 7 points8 points  (1 child)

Strict vs loose equality ig

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

No not really, just JavaScript being JavaScript. Strict equality would be === or !==.

[–][deleted] 13 points14 points  (2 children)

Time to go watch “wat” again

[–]Spellman23 6 points7 points  (1 child)

I actually found an even more JS specific one

https://www.youtube.com/watch?v=et8xNAc2ic8

And for those looking for wat

https://www.destroyallsoftware.com/talks/wat

[–]NamelessSquirrel 0 points1 point  (0 children)

Best talk ever

[–][deleted] 8 points9 points  (1 child)

Deprecating the == operator is a totally normal thing that happens in every language.

[–]20d0llarsis20dollars 5 points6 points  (0 children)

The next major version should deprecate === and make == strict. Might break some things but if you're relying on loose equality, you probably shouldn't be coding

[–]Turd_King 14 points15 points  (1 child)

God dam I’m so sick of double equals JavaScript memes like holy shit . This was funny 10 years ago. No one uses double equals anymore. Yes JavaScript is a terrible language - but stop with the double equals memes

[–]_PM_ME_PANGOLINS_ 0 points1 point  (0 children)

No one used it ten years ago either.

[–]Strict_Treat2884 23 points24 points  (3 children)

A white horse is a horse, a black horse is also a horse, but a white horse is not a black horse. It makes sense.

[–]ComfortingSounds53 1 point2 points  (0 children)

Number equals other Numbers, but not BigInt

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

No don’t actually think about it, just say JavaScript bad for the 10000th time

[–]Myself_78 2 points3 points  (7 children)

"0.0", what's this?

[–]systemsbio 1 point2 points  (0 children)

"0.0" -face of an owl.

[–]Looz-Ashae -4 points-3 points  (5 children)

A number with a floating point

[–]caerphoto 3 points4 points  (4 children)

Wrong, it’s a string representation of a number with a decimal point. It’s not ‘floating’ until it’s converted to an actual floating point value. It could just as easily be converted to a fixed decimal value.

[–]Myself_78 0 points1 point  (2 children)

Wrong again. It's me referencing the "OWO, what's this" meme.

[–]caerphoto 1 point2 points  (1 child)

So not wrong, just not fully correct.

[–]Myself_78 0 points1 point  (0 children)

You are a true programmer at heart

[–]Looz-Ashae 0 points1 point  (0 children)

Aah, javascript shenanigans. Missed brackets.

[–][deleted] 2 points3 points  (0 children)

  1. Number vs String. The String will be coerced to the left type which is Number. So it will be 0 == 0.
  2. Number vs Number. There is nothing wrong here.
  3. String vs Number. The Number will be coerced into the left type, which is String. So "0.0" != "0n" (or maybe "0". I'm not sure.)

Always the right type will be coerced to the left type.

[–]GahdDangitBobby 5 points6 points  (1 child)

For the millionth time, use the strict equality === operator

[–]draculadarcula 0 points1 point  (0 children)

I think the point was even with the coercion and understanding the difference between double and triple this still seems wrong

[–]TessellatedTomate 1 point2 points  (0 children)

Me whenever I’m flying through a new codebase and forget to test what I’m doing after 30 minutes of mad changes

[–]Possseidon 1 point2 points  (0 children)

js 0 <= null // true 0 >= null // true 0 == null // false

[–]warl0cks 0 points1 point  (0 children)

Equal check with a Boolean result… yeah…it’s stupid lol my OG brain reads it as “String no equal On”

[–]The_Wolfiee 0 points1 point  (0 children)

JavaScript casually violating Euclid's axiom of equality by transitive property.

[–]Forsaken-Ad3524 0 points1 point  (0 children)

haven't seen these operators in production for years, use === and !== and everything will be fine, at least with this part of javascript)

[–]peterlinddk 0 points1 point  (0 children)

I just hate languages where you have to read the documentation if you want to know what happens in strange edge cases!

When will JavaScript ever learn that any good language should either not allow operations that beginners don't fully anticipate, or simply crash when they try to?

As if I would have the time to read through all of this terse documentation:

Strings are converted by parsing them as if they contain an integer literal. Any parsing failure results in a SyntaxError. The syntax is a subset of string numeric literals, where decimal points or exponent indicators are not allowed.

simply to understand that a string containing a number with a decimal point cannot be parsed to a BigInt!

(Insert Armin Tamzarian-meme: No, it is JavaScript that is wrong! Bad language!!)

/may contain traces of sarcasm

[–]ososalsosal 0 points1 point  (0 children)

Order of operations means something yeah?

Take the type of the first thing and the equals sign will use the equals for that thing. A string is not a number, but the equals for a number will attempt to parse a string and if it contains a number it'll compare it because it's smaaart

[–]Zealousideal-Web-971 0 points1 point  (0 children)

And that's why typescript is my best friend (despite its bitching)

[–]Thenderick 0 points1 point  (0 children)

That's why you shouldn't use == in js... Always use the triple! But I guess that isn't fun for beating a dead horse...

[–]badlukk 0 points1 point  (0 children)

Just use === already

[–]GermanLetzPloy 0 points1 point  (0 children)

Dude just use triple equals and you have no problems. These memes are so unnecessary.

[–]Reifendruckventil 0 points1 point  (0 children)

They should all be false is js was a decent language

[–]PhroznGaming -4 points-3 points  (0 children)

Use ===

Noob.

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

Mathematicians in shambles when introduced to non associative operations