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.
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.
The issue there is that TS allows dropping out of the type system with `any`, so it might not actually be checking the types you're comparing, so I'd still use ===.
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.
Aren't you implicitly assuming that TS's number === JS's Number and TS's string === JS's String? You could say == is extended for TS's types(number/string), but the JS == still exists: x as any == y as any;
I can see what you're saying, but I think that argument would be a lot stronger if == compiled to ===. If you want an operator with ==='s semantics, it's there; providing == and claiming it behaves like === just seems like an opportunity for annoying surprises if something slips through the cracks. Since == doesn't compile to ===, I wouldn't use it unless I understood its semantics and wanted them.
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.
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.
We fully embrace Javascript as dynamically typed language and when one does this, types on most cases will become irrelevant. Then also using === in the code means that the usage is explicitly required in this specific place and == will cause wrong result. But when === and == are the same, then we use strictly ==. Also read this: http://dmitry.baranovskiy.com/post/typeof-and-friends
If you are curious, please post some real life real working code where in your mind usage of === is absolutely needed and I try my best to explain how I would tackle that with ==.
>We fully embrace Javascript as dynamically typed language [...]
I won't outright dismiss your coding style because I don't know what your codebase looks like and maybe you're genuinely talented JS devs who know what they're doing (something I'm decidedly not) but your comment makes it sound like discouraging the use of '==' is not "embracing" JS's dynamism. I don't think I agree with that, actually there are a bunch of highly dynamic languages where comparison is not such a mess. The main problem with '==' is that it's highly inconsistent and intransitive (as showcased by TFA). It's tricky to figure out what evaluates to true or false when types don't match. It's not PHP bad but it's pretty damn bad.
> please post some real life real working code where in your mind usage of === is absolutely needed and I try my best to explain how I would tackle that with ==.
I think you're expending your energy for the wrong reasons. There is no need to be "clever" when writing code. Being explicit is always better. Being explicit is how bugs are avoided, how new people can enter your codebase, and how you can maintain your codebase in the future. If you spend time thinking about how to justify usage of something in your code, it has no justification being used.
Disagree. Nothing clever in this, just elementary JS knowledge. I claim that relying in types in dymanic language (always ===) is actually worse. Better is not rely on types.
Probably bad ;-) Seriously speaking all that comparison tables are pure academic stuff. In real code I honestly ever encountered a case where I have no clue whatsoever what both sides of equation are. To the claim that when you have such conditions, then you need to fix that and such code is bad to the bones. Real life code is much more boring - if (a == “b”) where there is no value possible for a where === would give different result. But, I like to alleviate that there is no beef for me in this discussion, i just wanted to show that, yes, someone still uses == and he is not looney ;-)
The types are there, are to some extent you always have to rely on them. You can't call .push() on a string, or pass a number to Object.keys(). I can't imagine a situation where using == even works as you expect it to, aside from comparing numbers and strings that contain numbers. In which case the string should be converted to a number at the user input edge, as part of (but not the entire) input normalization, sanitation and validation phase.
> "We fully embrace Javascript as dynamically typed language and when one does this, types on most cases will become irrelevant."
That's not dynamic typing, that's weak typing.
Dynamic typing just means the types are omitted in the source code, but they're still there. typeof 3 is still 'number'. If you explicitly specify the types, you get TypeScript.
But weak typing means you can do things with disparate types that you can't normally do, usually by implicitly coercing one to the same type as the other.
The world has generally considered weak typing a very bad idea. Type coercion has too many edge cases and unintuitive/unexpected combinations. Even Lua is experimenting with runtime flags that disable type coercion such as "1" + 2. (That's the reason they have the .. operator btw.)
The only byproduct of weak typing that most people agree on keeping in modern languages is the concept of "truthy", but even then, languages have different ideas of what should be truthy. Clojure and Ruby say everything except nil and false are truthy, Python says "" and [] are also falsey, and I don't remember where JavaScript fully stands on this, but I know that null, undefined, false, and "" are at least falsey.
Yep, you are correct about generic truthy. We have standard library function empty(), which is custom (agreed internally what is empty) and which everyone knows. That solves many issues you pointed.
> The world has generally considered weak typing a very bad idea.
Now that is the type of thing that screams for supporting evidence.
> Type coercion has too many edge cases and unintuitive/unexpected combinations.
That depends on the implementation. I would say Perl handles this problem neatly by making the coercion done entirely based on the operator used, so it's always obvious.
That's a fair point, but I think this article shows that weak typing in JS is actively avoided by most people. That's why the article is interesting in the first place. I don't know if PHP heavily relies on weak typing though, I haven't used it in 9-10 years. But JS doesn't rely on it. It's just there, and easily avoided.
I'm certain that at least 95% of our code would be safe if you replaced === with ==. We likely have some edge cases that would blow up, but by and large, we don't really depend on the type checking of identity. We write code as if you explicitly declare type on JS.
I don't think using equality is inherently bad. I think that it can lead to a lot of bad habits for junior devs who don't understand some basics about types. I'm not against weak/implicit typing systems, but my experience has taught me that junior devs (and student alike) are prone to errors extending from the type system.
If you do arithmetic's it's converted to Number, if you concatenate it's converted to string. It's however unfortunate that + is used for both concatenation and addition. The advantage is flexibility and convenience. You can for example have functions that takes almost anything as input and does what you want, so that you do not have to tell the computer in detail what types to use.
For example in Node.JS callback convention the last argument is always the callback functions, even if the function takes 4 arguments, you can put the callback in the 3:rd argument and it will figure out which one is the callback function. Then the first parameter in the callback function is either null or an Error.
Another example is RegeExp where you can write if( str.match(/foo/) ) instead of if ( str.match(foo) === null )
It's also convenient that empty strings are "falsy" which allow you to write if(!foo) instead of if( foo==="" || foo===undefined || foo===0 )
Ok, but I really don't think that any of those conveniences outweigh the downsides of total lack of typing.
Also - you can use the == 'falsiness' whilst still in a strict scenario.
If you take the typing argument one step further, into Typescript, the advantages of just some basic typing become considerably more clear as the compiler/transpiler picks up loads of problems that wouldn't be found otherwise.
The only problem I can see is mixing strings and numbers. But there are probably more errors someone pro types would say is type errors while someone pro dynamic/loose typing would say is not ... Here's a nasty bug that took me like two hours to debug (this is only two lines, but imagine a sea of code where such thing could easily hide). Can you spot it ?
var foo = [];
foo.push["bar"];
You could say it's a type error. It's however not caught by neither TypeScript or Flow.
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 `==`.
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.
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 ===.
> 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.
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?
I tried my best, but I can't control how other people interpret it. That's what comments are for after all, to deal with information asymmetry like this.
I just don't get it. What's wrong with expressing my love for a language that I love? I am not even asking for anyone to switch to JS, just expressing my feel.
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.
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.
Sure, until I end up working on someone else’s codebase, and have to clean up the “fun” and “creative” code they thought would be a better idea than “simple,” “idiomatic,” and “explicit”!
Do you mean you prefer to just follow instructions given by product managers as a robot rather than exercising your creativity and enjoy coding? Or am I reading your statement wrongly? That sounds like a terrible job to have.
I'm interpreting "creative and fun" as either synonymous with "overly clever" (which is hard to read, hard to debug, and hard to maintain [0][1]), or written a non-standard way just for the sake of being different. For example, here's a collection of FizzBuzz solutions[2]. Most of these are incredibly unreadable.
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 '=='.
> 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 `==`).
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.
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.
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 ==.
In that sort of case I like to use explicit type casting, e.g.
if (Number(myNum) === 2) {}
For me this also extends to using `Boolean(val)` instead of `!!val`, etc.; though I understand the appeal of those nifty one-liners, I think they cause confusion in many places and don't communicate intent nearly as well.
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.
This is especially useful if you are using TypeScript (or Flow I assume) because the type checker can give you an error at compile time. After performing the runtime check, TypeScript will know that null/undefined is not possible.
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.
> `==` 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.
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.)
* 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?
The anemic JS standard library is a much bigger problem, resulting with bloated bundles with all sorts of basic stuff in them (lodash, timezones, etc). Even worse, the fact that things aren't standard means that multiple "standard" library replacements might be used, depending on the preference of the developers who wrote the library you depend on (ramda? lodash? individual lodash subpackages? etc). Small modules don't solve the problem, because you can still have 5 small modules with a slightly different API doing the same thing, all of them used by different libraries you depend on due to different preferences of their authors.
IMO TypeScript fits like a glove on top of JS and largely gets rid of the language problems, leaving mainly library / ecosystem problems.
Dart did many things wrong, but one thing it did do right was the standard library. If we had a standard library like that in JS, that would change everything.
Another serious problem are modules. The fact that the ES6 loader is "open ended" just means that we don't really have a solution to the problem of distributing JS. The fact that HTTP2 push is somewhat broken means we can't rely on it to load ES6 modules either.
At the very least we need the concept of absolute and relative module identifiers. Even if the specifics are implementation-defined, e.g.
* whether module ids are used,
* or content hashes,
* or absolute paths (or maybe npm module names with the version?)
the ability to provide absolute modules via a DLL:
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.
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.
124 comments
[ 4.1 ms ] story [ 209 ms ] threadSo 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.
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.
That said, if you mix types between comparison operands or inside arrays then you probably have bigger problems than "==" semantics. :-)
And the engine makes it as fast as === https://github.com/dperini/nwsapi/pull/11#issuecomment-38327... (Generally else == is slower than ===)
I can think of one instance where I needed identity instead of equality, and I took the time to refactor to ensure that equality would work.
If you are curious, please post some real life real working code where in your mind usage of === is absolutely needed and I try my best to explain how I would tackle that with ==.
I won't outright dismiss your coding style because I don't know what your codebase looks like and maybe you're genuinely talented JS devs who know what they're doing (something I'm decidedly not) but your comment makes it sound like discouraging the use of '==' is not "embracing" JS's dynamism. I don't think I agree with that, actually there are a bunch of highly dynamic languages where comparison is not such a mess. The main problem with '==' is that it's highly inconsistent and intransitive (as showcased by TFA). It's tricky to figure out what evaluates to true or false when types don't match. It's not PHP bad but it's pretty damn bad.
I think you're expending your energy for the wrong reasons. There is no need to be "clever" when writing code. Being explicit is always better. Being explicit is how bugs are avoided, how new people can enter your codebase, and how you can maintain your codebase in the future. If you spend time thinking about how to justify usage of something in your code, it has no justification being used.
How's your score on the minesweeper? :)
That's not dynamic typing, that's weak typing.
Dynamic typing just means the types are omitted in the source code, but they're still there. typeof 3 is still 'number'. If you explicitly specify the types, you get TypeScript.
But weak typing means you can do things with disparate types that you can't normally do, usually by implicitly coercing one to the same type as the other.
The world has generally considered weak typing a very bad idea. Type coercion has too many edge cases and unintuitive/unexpected combinations. Even Lua is experimenting with runtime flags that disable type coercion such as "1" + 2. (That's the reason they have the .. operator btw.)
The only byproduct of weak typing that most people agree on keeping in modern languages is the concept of "truthy", but even then, languages have different ideas of what should be truthy. Clojure and Ruby say everything except nil and false are truthy, Python says "" and [] are also falsey, and I don't remember where JavaScript fully stands on this, but I know that null, undefined, false, and "" are at least falsey.
Now that is the type of thing that screams for supporting evidence.
> Type coercion has too many edge cases and unintuitive/unexpected combinations.
That depends on the implementation. I would say Perl handles this problem neatly by making the coercion done entirely based on the operator used, so it's always obvious.
I think the direction of mainstream programming languages over the past 20 years is overwhelmingly clear about this.
There's only one language that I know of that's still in popular use and that likes weak typing.
> That depends on the implementation. I would say Perl handles
Yep that's the one.
As much as I wish it wasn't so, I believe PHP sees more activity currently than Perl, and it's also weakly typed.
Javascript itself is weakly typed as well, which is why we're all having this discussion.
I would say that two of the most popular languages (probably the two most popular new languages) of the last two decades have been weakly typed.
I don't think using equality is inherently bad. I think that it can lead to a lot of bad habits for junior devs who don't understand some basics about types. I'm not against weak/implicit typing systems, but my experience has taught me that junior devs (and student alike) are prone to errors extending from the type system.
Ok, but why? Do you not think there's an advantage in having a difference between strings and numbers?
"1" == 1?
You can chose that if you want, surely, but what are the advantages of 'embracing' this?
For example in Node.JS callback convention the last argument is always the callback functions, even if the function takes 4 arguments, you can put the callback in the 3:rd argument and it will figure out which one is the callback function. Then the first parameter in the callback function is either null or an Error.
Another example is RegeExp where you can write if( str.match(/foo/) ) instead of if ( str.match(foo) === null )
It's also convenient that empty strings are "falsy" which allow you to write if(!foo) instead of if( foo==="" || foo===undefined || foo===0 )
Also - you can use the == 'falsiness' whilst still in a strict scenario.
If you take the typing argument one step further, into Typescript, the advantages of just some basic typing become considerably more clear as the compiler/transpiler picks up loads of problems that wouldn't be found otherwise.
let x:number[] = []; x.push("x");
Here, the transpiler will catch the error of trying to push a string to a number array.
Typing is your friend, and it will in almost all cases help you write cleaner and safer code.
does it not make sense to just remove it from the language completely? who is deciding that?
The best solution currently is to have linter rules enforcing ===.
No, because you'd wreck quite a bit of the internet with that.
> who is deciding that?
ECMA TC39
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.
nope. none of that. there are plenty of fun, dynamic languages that aren't the horrible pile of shit that is raw javascript.
> And once you master it you become a ninja.
wait, was this sarcasm? hard to tell..
1. I was making a generalized statement around JS, not specifically '=='. That's a misinterpretation of my statement.
>"my programming language is perfect"
2. I did not say JavaScript is perfect. That's a misinterpretation of my statement.
>"if you don't like it you're just too dumb to get it"
3. I did not say "if you don't like you're just too dumb." That's a misinterpretation of my statement.
JavaScript really _isn't_ all that expressive.
I just don't get it. What's wrong with expressing my love for a language that I love? I am not even asking for anyone to switch to JS, just expressing my feel.
Thanks for pointing that out.
I think might be due to the downvotes somehow. It makes you wonder if you did something wrongly or it is simply people disagreeing with you.
Sure! For starters, you can write
Because `undefined` gets coerced to `null`, it saves you from writing: And, because it's shorter, it's even allowed by [some JS linters](https://standardjs.com/).There you have your JS ninja trick to handle two distinct null types^TM .
Yes, a ninja of the "undefined is not a function" wars.
In my experience, code that is "slightly creative and fun" is unreadable and not actually useful for creating working products as a part of a team.
[0]https://www.simplethread.com/dont-be-clever/
[1]http://www.delabs.io/clever-code-is-bad-code/
[2]https://ditam.github.io/posts/fizzbuzz/
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 `==`).
https://www.destroyallsoftware.com/talks/wat
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
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.
The type information simply is not there.
https://eslint.org/docs/rules/eqeqeq
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
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.
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.
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.
For those not aware, you can specify a rule in [js/es/ts]lint to allow only these cases.
`const isString = myVar => typeof myVar !== 'string'`
This is more reusable and more idiomatic in my opinion than null/undefined checks
See this example https://goo.gl/AyoC3T
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.
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.
Wut?
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.)
* 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.
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?
IMO TypeScript fits like a glove on top of JS and largely gets rid of the language problems, leaving mainly library / ecosystem problems.
Dart did many things wrong, but one thing it did do right was the standard library. If we had a standard library like that in JS, that would change everything.
Another serious problem are modules. The fact that the ES6 loader is "open ended" just means that we don't really have a solution to the problem of distributing JS. The fact that HTTP2 push is somewhat broken means we can't rely on it to load ES6 modules either.
At the very least we need the concept of absolute and relative module identifiers. Even if the specifics are implementation-defined, e.g.
* whether module ids are used,
* or content hashes,
* or absolute paths (or maybe npm module names with the version?)
the ability to provide absolute modules via a DLL:
would be of incredible help.That, or maybe we can fix HTTP2 push.
I mean, JS definitely has serious problems, but equality coercion is not one of them :)
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