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 ==.
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.
* 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.
"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?
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.
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.
Plenty of beginners I'm sure. People who come from languages where == is not broken will probably default to using it, if only because of muscle memory. It might not be immediately obvious that it's broken too which makes it worse.
Yes. In our codebase it is forbidden to test for true/false, only truthy/falsy is allowed. The only place where === is needed and allowed is testing for if function argument is omitted. Otherwise == and yes, all developers understand that and agree and no, we haven’t had any bugs because of that. Big and complex web app, not my first, the previous gig was even bigger, same approach. Works like a charm.
It's idiomatic to use == to check for both null and undefined at least.
A lot of people seem to have a perception of languages as being handed down by some language gods, and apparent problems with the language get explained away by "mere users" lacking knowledge, perspective, discipline, etc.
I do, when I know the types match. Also, I always use == to test if something is either null or undefined; cases where the distinction matters are extremely rare, and this looks too silly: typeof foo === "undefined" || foo === null.
We use it to check if a value is null or undefined (`foo == null`) is true for both `foo = null` and `foo = undefined`, which is pretty handy. Other than that, we don't use `==`.
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.
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.
> does it not make sense to just remove it from the language completely?
The way syntax is "removed from the language" in JS is by introducing commonly-used lint rules that disallow them, and that has already happened with `==`: https://eslint.org/docs/rules/eqeqeq . As long as the community makes it so a standard project setup has a linter with good defaults, `==` can effectively be removed from JavaScript without having to break nearly every website in existence (which is what would happen if browsers decided to start crashing on `==`).
You can't remove JavaScript features without breaking websites. The one exception was when the strict mode pragma was added, but that was a one-off, and there's too much resistance now to add more pragmas (they tried that with "strong mode").
The best solution currently is to have linter rules enforcing ===.
I'm actually surprised that it doesn't give you at least a warning when you "use strict;". That being said plenty of JS linters will yell at you if you use '=='.
> 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.
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.)
[+] [-] snek|7 years ago|reply
[+] [-] alangpierce|7 years ago|reply
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.
[+] [-] always_good|7 years ago|reply
It's like every time you defensively throw in a nil-guard just in case: everyone now has to go "wait, can nils really get this far into the system?"
You just start wasting the time of the people experienced enough to identify it as a potential problem.
[+] [-] thatswrong0|7 years ago|reply
[+] [-] tenaciousDaniel|7 years ago|reply
if (myNum === 2 || myNum === '2') {}
It's very easy for developers to mistakenly "see" the third equality symbol and get confused by the intent of the code.
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] spion|7 years ago|reply
* 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|7 years ago|reply
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?
[+] [-] teddyh|7 years ago|reply
https://www.destroyallsoftware.com/talks/wat
[+] [-] brianzelip|7 years ago|reply
[+] [-] giancarlostoro|7 years ago|reply
[+] [-] tenaciousDaniel|7 years ago|reply
[+] [-] linkmotif|7 years ago|reply
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.
[+] [-] ttty|7 years ago|reply
[+] [-] DougBTX|7 years ago|reply
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.
[+] [-] simias|7 years ago|reply
[+] [-] atirip|7 years ago|reply
[+] [-] skrebbel|7 years ago|reply
That said, if you mix types between comparison operands or inside arrays then you probably have bigger problems than "==" semantics. :-)
[+] [-] slikts|7 years ago|reply
A lot of people seem to have a perception of languages as being handed down by some language gods, and apparent problems with the language get explained away by "mere users" lacking knowledge, perspective, discipline, etc.
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] 11235813213455|7 years ago|reply
And the engine makes it as fast as === https://github.com/dperini/nwsapi/pull/11#issuecomment-38327... (Generally else == is slower than ===)
[+] [-] marijn|7 years ago|reply
[+] [-] mishoo|7 years ago|reply
[+] [-] paradite|7 years ago|reply
[+] [-] christophilus|7 years ago|reply
[+] [-] yoklov|7 years ago|reply
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] bazani|7 years ago|reply
[+] [-] raxxorrax|7 years ago|reply
[+] [-] yifanl|7 years ago|reply
[+] [-] lucideer|7 years ago|reply
e.g.:
- say there are 100 or so blocks, 20 are checkmarks
- if I click on 40, and get 10 checks, 30 blank, that means I got 30/20 wrong
[+] [-] yoava|7 years ago|reply
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|7 years ago|reply
I wrote tens of thousands of lines of JS (e.g. this library https://github.com/photopea/UPNG.js ), I never used "===" in my life :D
[+] [-] slikts|7 years ago|reply
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.
[+] [-] sadjfoadsf|7 years ago|reply
[+] [-] unknown|7 years ago|reply
[deleted]
[+] [-] keymone|7 years ago|reply
does it not make sense to just remove it from the language completely? who is deciding that?
[+] [-] Nimelrian|7 years ago|reply
No, because you'd wreck quite a bit of the internet with that.
> who is deciding that?
ECMA TC39
[+] [-] alangpierce|7 years ago|reply
The way syntax is "removed from the language" in JS is by introducing commonly-used lint rules that disallow them, and that has already happened with `==`: https://eslint.org/docs/rules/eqeqeq . As long as the community makes it so a standard project setup has a linter with good defaults, `==` can effectively be removed from JavaScript without having to break nearly every website in existence (which is what would happen if browsers decided to start crashing on `==`).
[+] [-] slikts|7 years ago|reply
The best solution currently is to have linter rules enforcing ===.
[+] [-] simias|7 years ago|reply
[+] [-] paradite|7 years ago|reply
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.
[+] [-] brookside|7 years ago|reply
[+] [-] jmull|7 years ago|reply
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.)
[+] [-] etimberg|7 years ago|reply
[+] [-] malmsteen|7 years ago|reply
Wut?
[+] [-] kenbellows|7 years ago|reply
[+] [-] danschumann|7 years ago|reply
[+] [-] hamandchris|7 years ago|reply
[+] [-] bacro|7 years ago|reply