
JavaScript Equality Minesweeper - bennettfeely
https://slikts.github.io/js-equality-game/
======
snek
I see a lot of comments here suggesting that == is okay to use if you know
what you're doing or if the types on both sides match or if this or if that.
Writing idiomatic code is all about being expressive and being explicit. Even
in the most common case, testing for null or undefined, it's absolutely not
clear what is actually happening or what the intent is. I write a lot of JS,
and I've never had any justifiable reason to use ==.

~~~
alangpierce
Depending on your conventions for null/undefined (another annoying wart of
JavaScript), I think it often makes sense to treat `== null` as a special
allowed case. In the code I work in, `== null` is strongly encouraged (but not
required) as the way of doing null checks, and all other uses of `==` are
disallowed by lint. Just like our other patterns and conventions, it's
something people pick up reasonably quickly as they're introduced to the code,
nothing tricky, just a little pattern that acts as a concise replacement to
the `?` operator from CoffeeScript.

The alternatives are writing `x === null || x === undefined` everywhere (which
might lead to people just picking one out of laziness, leading to bugs), doing
things like `if (x)` (which we still do sometimes, but can lead to subtle
falsy-related bugs if you're not careful), or to do careful bookkeeping of
when variables might be null vs undefined. In my opinion, the null/undefined
distinction is more cognitive overhead than the benefit it provides, so it's
best to just check for both at the same time and never intentionally treat
them as different. Given that mindset, I think the `== null` pattern is
slightly unfortunate, but better than the alternatives.

~~~
Rumudiez
My team checks for types, not for null.

`const isString = myVar => typeof myVar !== 'string'`

This is more reusable and more idiomatic in my opinion than null/undefined
checks

~~~
jscissr
But then you have the problem that typeof null === 'object'.

------
spion
The problem with this and the wat talk is that

* you don't actually see the case-space (value space) of all the comparisons that _do_ work as expected, and

* you don't a sense of what is the likelihood that these sort of comparisons would happen in real world code

Some of them like the empty string are likely to happen from user input, but
Typescript mitigates those by forcing you to e.g. use Number(inputField.value)
to conver to number and complaining about the assignment otherwise.

Others pretty much never ever happen - instead of comparing 1 or -1 to true,
you're more likely to use if (val) which casts to boolean, and the truthy
table is different from the equality comparison table (it makes a bit more
sense)

Most of the real world comparisons are to non-empty strings or numbers, and
those are only equal to arrays in some cases - but its rare for an actual
array to be produced by anything. Things you know are arrays already you don't
compare using "==" to begin with.

So yeah, in practice the confusing rules of JS equality comparison don't
really matter all that much.

~~~
ryanong
"So yeah, in practice the confusing rules of JS equality comparison don't
really matter all that much."

I run into this all the time. Plenty of junior devs I work with do this.
Unfortunately we haven't implemented typescript yet. Yea === solves this
problem but I wish there was a deprecation path for ==. Why can't we figure
out as a community how to deprecate horrible javascript apis? Why can't we as
a community figure out how to have a good standard library?

~~~
haburka
The deprecation path for bad apis is to use eslint. If you make it so you
can’t merge without eslint passing then you have effectively deprecated
syntax.

------
teddyh
“Let’s talk about Javascript!”

[https://www.destroyallsoftware.com/talks/wat](https://www.destroyallsoftware.com/talks/wat)

~~~
brianzelip
So great. There actually are 16 NaNs in the Batman song!

------
linkmotif
Fun game. Really captures the spirit of the subject. Great idea!!

I’m not one to pride myself on ignorance, but the JS equality operator is
ridiculous and therefore, IMO, not worthy of the mental energy it demands.

> How well do you know the rules for the == operator in JavaScript?

Well enough to use `===`. I’ve noticed in my code every time I’m tempted to
use `==`, I always end up finding a better way. `==` is basically code smell
that only really smart people should use.

~~~
wlesieutre
> `==` is basically code smell that only really smart people should use.

And then cross your fingers that no one else ever has to look at or work on
that code because they might not pick up on whatever "smart" reason the ==
operator was used.

------
ttty
It's so funny. Anybody still using == with js?

~~~
DougBTX
I'm interested to know what people think about this with TypeScript - quite a
lot of the weird behaviour in plain JS is rejected by the compiler, eg, "true
== 1" evaluates to true in plain JS, but is a compiler error in TypeScript
since it rejects bool vs number equality checks.

So with TypeScript code, I've been continuing to use == as in most other
languages, with the expectation that any odd comparisons will be flagged by
the compiler. On the other hand, I've not verified myself that it catches them
all, so I wonder if anyone has come across other edge cases with this that
could cause problems down the line.

~~~
kbp
I prefer it when Typescript tries to provide static type checking for
Javascript rather than providing checking for how they wish Javascript was.
`(x: number, y: string) => x == y` is an error because 'this condition will
always return false'. In what language? There are linter rules for enforcing
=== over ==; Typescript having incorrect type definitions to try and make sure
you only use == like === seems like a really poor solution to that.

~~~
arisb
I'm guessing you can't use `(x: number, y: string) => x === parseInt(y)`?

~~~
jaaames
As long as you feed parseInt it's second radix parameter you can :p

------
bazani
Well, looks like my knowledge is negative. I clicked the box random and when i
asked for my result i was 245% wrong. O_o'

~~~
raxxorrax
Probably some badly placed equality operator in the script.

------
yoava
Super cool application, and can teach a lot about why you should use ===
instead of == in JavaScript.

The only legit case to use == is if you are

1\. Insane

2\. The kind of person who changes Java 1 object to equal 2

------
IvanK_net
I don't think it is useful to know the behaviour of JS in such cases. In
practice, you rarely compare strings with numbers, or objects with booleans.

I wrote tens of thousands of lines of JS (e.g. this library
[https://github.com/photopea/UPNG.js](https://github.com/photopea/UPNG.js) ),
I never used "===" in my life :D

~~~
slikts
The implicit coercion rules don't matter if you make sure to convert the types
explicitly, but then you're just relying on your discipline. You might be able
to pull it off individually, but it starts mattering more when working with
other people.

Also, from a brief glance at your code example, you don't seem to have caught
up with other current best practices like linting or modules.

~~~
awestroke
You don't have to rely on discipline, you can use tooling like ESLint or Flow
to make sure there are no implicit conversions in the codebase.

~~~
TheDong
eslint absolutely can't figure out whether '==' will implicitly convert its
arguments or not.

The type information simply is not there.

~~~
awestroke
eslint can disallow == for anything but `== null`. Problem solved.

[https://eslint.org/docs/rules/eqeqeq](https://eslint.org/docs/rules/eqeqeq)

~~~
TheDong
This thread is about not using `===`; it's obviously true that it can be
disallowed entirely, but it can't be allowed based on whether or not it will
coerce, which was the context of the thread.

------
sadjfoadsf
There's a lot of ===ers in here. I can't say I've ever experienced a situation
where not using === has caused an issue. However, I can think of many cases
where === would have caused an issue. In other words, I've found == better
handles unintended logical errors. Nonetheless, the equality chart is
difficult to memorize. Luckily, I typically only deal with a subset of it.

------
keymone
it seems equality operator in javascript is good for nothing but being a
source of confusion and a target of jokes.

does it not make sense to just remove it from the language completely? who is
deciding that?

~~~
paradite
_> it seems equality operator in javascript is good for nothing but being a
source of confusion and a target of jokes._

I would say that's the defining characteristics of JavaScript.

It makes it fun to write JavaScript with its quirkiness and "dynamic" nature.
And once you master it you become a ninja.

Compare it to Java or Golang where you are restricted by the language syntax
and anything slightly creative and fun is either not supported or not
idiomatic.

~~~
simias
You'll have to show me one inventive and useful "ninja" trick revolving around
the use of '=='. Sounds to me like the classic "my programming language is
perfect and if you don't like it you're just too dumb to get it". This is
pretty common among C developers in my experience but I didn't expect that
from JS enthusiasts. What's next, PHP ninjas?

~~~
thalesmello
> You'll have to show me one inventive and useful "ninja" trick revolving
> around the use of '=='

Sure! For starters, you can write

    
    
        if (foo == null) { ... }
    

Because `undefined` gets coerced to `null`, it saves you from writing:

    
    
        if (foo === null || foo === undefined) { ... }
    

And, because it's shorter, it's even allowed by [some JS
linters]([https://standardjs.com/](https://standardjs.com/)).

There you have your JS ninja trick to handle two distinct null types^TM .

~~~
simias
I would argue that it's only a "feature" because JS has this needless
dichotomy between null and undefined so it's basically two issues cancelling
each-other, but that sounds a lot like moving the goalpost so I'll concede the
point.

~~~
thalesmello
Just to make sure, my "ninja trick" was meant in an ironic manner. In my
opinion, it sucks JavaScript has two equality operators, and it's inexcusable
for it to have two different null types. That fact that you can use the forer
to check for the latter with less code doesn't make either okay in any sense.

------
brookside

      NaN == NaN 
    

is falsy, no? (Shows as truthy in the game, unless I am misunderstanding.)

~~~
jmull
NaN == NaN is falsy (so is NaN === NaN, for that matter).

But when I played the game, it looked to me like the game correctly claimed it
is falsy. (Though I'm not 100% sure I know what the notation the game uses
means.)

------
malmsteen
True == 1 but False "not ==" 0

Wut?

~~~
kenbellows
Not sure what you mean, can you explain more? When I open my console, I get:

    
    
        > true == 1
        -> true
        > false == 0
        -> true
    

Do you get something different? Or is the game claiming something different?

~~~
malmsteen
the game claims something different no ?

------
danschumann
`true == [1]` is news to me

------
hamandchris
There needs to be a PHP version of this.

------
bacro
668% wrong!! :D

