14 ms·
JavaScript Equality Minesweeper
- ttty 8y agoIt's so funny. Anybody still using == with js?
- simias 8y agoPlenty 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.
- CraneWorm 8y agoPeople relying on its broken behaviour :)
- DougBTX 8y agoI'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.
- slikts 8y agoThe 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 ===.
- kbp 8y agoI 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.
- Sacho 8y agoAren'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;
- kbp 8y agoI 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.
- arisb 8y agoI'm guessing you can't use `(x: number, y: string) => x === parseInt(y)`?
- jaaames 8y agoAs long as you feed parseInt it's second radix parameter you can :p
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- slikts 8y agoIt'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.
- skrebbel 8y agoEverybody who uses >= and <= implicitly uses ==. That said, if you mix types between comparison operands or inside arrays then you probably have bigger problems than "==" semantics. :-)
- paradite 8y agoPeople who writes `if(value)`
- blauditore 8y agoBut that's not the same; it's about truthy-ness. E.g. -1 and 1 are both truthy, but not loosely equal.
- paradite 8y agoYou are right. I confused truthy-ness with '== true' for some reason, didn't write much JS lately.
- paulintrognon 8y agoThat's weird, I would thought that if(value) was the equivalent of if(value == true). Learned something today!
- pythonaut_16 8y agoYou can force cast a boolean by doing if(!!value == true) {}, but at that point you might as well just say if(value)
- darepublic 8y agoTruthy ? A : B Truthy && A Falsy || fallback
- 11235813213455 8y agoFor typeof obj == '..' you don't need === since typeof always returns a string And the engine makes it as fast as === https://github.com/dperini/nwsapi/pull/11#issuecomment-383275455 https://github.com/dperini/nwsapi/pull/11#issuecomment-38327... (Generally else == is slower than ===)
- deleted 8y ago[deleted]
- atirip 8y agoYes. 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.
- deleted 8y ago[deleted]
- noxToken 8y agoBut why? I'm having a hard time understanding why you'd outright ban identity (===) and only allow equality (==). 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.
- atirip 8y agoWe 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 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 ==.
- simias 8y ago>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.
- christophilus 8y agoWe 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 `==`.
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- marijn 8y agoAs long as the types on both sides match, the behavior of == is perfectly reasonable, and in typical uses, this will be the case.
- mishoo 8y agoI 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.
- deleted 8y ago[deleted]
- yoklov 8y agoFirefox has a few million lines of JS code and the coding standard prefers `==` to `===`. I don't think it's linted for though.
- keymone 8y agoit 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?
- slikts 8y agoYou 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 ===.
- Nimelrian 8y ago> it seems equality operator in javascript is good for nothing but being a source of confusion and a target of jokes. if (someValue != null) { // someValue is neither null nor undefined } > does it not make sense to just remove it from the language completely? No, because you'd wreck quite a bit of the internet with that. > who is deciding that? ECMA TC39
- paradite 8y ago> 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.
- keymone 8y ago> It makes it fun to write JavaScript with its quirkiness and "dynamic" nature. 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..
- 8y ago
- teddyh 8y ago“Let’s talk about Javascript!” https://www.destroyallsoftware.com/talks/wat https://www.destroyallsoftware.com/talks/wat
- tenaciousDaniel 8y agoThis will never stop being funny.
- giancarlostoro 8y agoGreat video. Wish it was much longer honestly.
- brianzelip 8y agoSo great. There actually are 16 NaNs in the Batman song!
- IvanK_net 8y agoI 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 8y agoThe 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.
- deleted 8y ago[deleted]
- awestroke 8y agoYou 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 8y agoeslint absolutely can't figure out whether '==' will implicitly convert its arguments or not. The type information simply is not there.
- bazani 8y agoWell, 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 8y agoProbably some badly placed equality operator in the script.
- yifanl 8y agoThe calculation function is provided on the page.
- lucideer 8y agoThe logic here is that there's three possible answers, and also a lot more empty blocks than checkmarks or Xes. 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
- snek 8y agoI 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 ==.
- always_good 8y agoAgreed. The second you use `==`, now everyone else who encounters it has to do their own research to see if you indeed meant it. 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.
- SeriousM 8y agoThank you, that was a well written summary of my thoughts.
- tenaciousDaniel 8y agoyeah if I'm doing any kind of loose type-checking I make it explicit. 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.
- kenbellows 8y agoIn 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.
- thatswrong0 8y agoI only ever use == to do “x == null”, to check if x is undefined or null, but not any other falsey value like 0.
- danschumann 8y ago`true == [1]` is news to me
- linkmotif 8y agoFun 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 8y ago> `==` 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.
- malmsteen 8y agoTrue == 1 but False "not ==" 0 Wut?
- kenbellows 8y agoNot 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 8y agothe game claims something different no ?
- brookside 8y agoNaN == NaN is falsy, no? (Shows as truthy in the game, unless I am misunderstanding.)
- etimberg 8y agoThe coercing between types only happens if the types are different.
- jmull 8y agoNaN == 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.)
- hamandchris 8y agoThere needs to be a PHP version of this.
- spion 8y agoThe 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 8y ago"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?
- spion 8y agoThe 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: provides 'lodash@2.0.5' { export ... // multiple things } provides 'other-module@version' { } 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 :)
- bacro 8y ago668% wrong!! :D
- yoava 8y agoSuper 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
- sadjfoadsf 8y agoThere'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.
- deleted 8y ago[deleted]