2

It took me a while to note to always use === in JavaScript instead of ==.

But today I noticed

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

seems identical as

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

from a table in the MDN docs.

I hope to know:

  1. are they really identical?
  2. is it recommended to use the form a == null instead of a === null || a === undefined?
nonopolarity
  • 130,775
  • 117
  • 415
  • 675
  • Check this: https://stackoverflow.com/a/27550756/3783478 – Rajesh Mar 16 '20 at 11:56
  • Check this table: https://stackoverflow.com/a/23465314/3082296 – adiga Mar 16 '20 at 11:57
  • They are identical. – Roberto Zvjerković Mar 16 '20 at 11:59
  • 1
    @Teemu only `null` and `undefined` pass the `a == null` condition – adiga Mar 16 '20 at 11:59
  • @Teemu guys, before shallow judgment is added for this question, DO NOTICE that `a == null` really is identical to `a === null || a === undefined`. Even the TC39 committee is using it – nonopolarity Mar 16 '20 at 12:00
  • 1
    @nonopolarity In your answer you're talking about `?.` operator, but in your question there's nothing about it ..? – Teemu Mar 16 '20 at 12:00
  • 2
    @Teemu Only `null == undefined` and vice versa is true https://stackoverflow.com/a/23465314/3082296. For example `0 == null` is false – adiga Mar 16 '20 at 12:02
  • @Teemu this is not instant noodles. Read the answer. The `?.` is only about how the TC39 checks whether something is `null` or `undefined` – nonopolarity Mar 16 '20 at 12:05
  • 1
    Amazing how things like this appear,. It's certainly a nice trick `a == null`. Would I personally use it. That's a tricky one!!,. It seems fine once you know, but like @nonopolarity mentions it's so very easy for others to miss-read, especially as most linting will complain. So, easy for another programmer to go, oh. look he forgot an extra `=`.. :) – Keith Mar 16 '20 at 12:12
  • 1
    @Keith I know, you can state something advanced, and in 3 seconds, 10 intermediate negative opinion comes in – nonopolarity Mar 16 '20 at 12:14
  • @nonopolarity Yeah,:) Well you got an upvote from me anyway. Your answer was well written, and I'm totally baffled by the down-votes.. :( – Keith Mar 16 '20 at 12:16
  • @Keith I found that sometimes, when a question or answer is not useful for users to get points, it is immediately downvoted, because, it is no immediate gratifications – nonopolarity Mar 16 '20 at 12:19
  • @Keith "*specially as most linting will complain*" you can configure your linter to allow `x == null` checks but not any other double equals. And if somebody is examining your code *without* using your lint settings, then they should stop. Alternative, if you're supplying code and not conforming to their lint settings, you should stop. So, all in all - linters shouldn't be an issue here. – VLAZ Mar 16 '20 at 12:36
  • @VLAZ but is this just ESLint,.. tried looking in JSLint & JSHint & standardJs, can't seem to find the option to just accept `== null` Of course ESLint is the one I use, but I did say most linters, not all. – Keith Mar 16 '20 at 13:30
  • @Keith JSLint is a bad stick to compare against as it's *really* opinionated. It alone spawned the ecosystem of other linters that allow for more options.As for JSHint, it has had the [eqnull](https://jshint.com/docs/options/#eqnull) rule since before even ESLint existed. – VLAZ Mar 16 '20 at 13:33
  • @VLAZ `JSLint is a bad stick to compare`,.. Yeah!!,. Well it's good to know if I did want to start using this, Linting has me covered. Make's me think again.. :) – Keith Mar 16 '20 at 13:39

1 Answers1

0

Yes, they are identical, except for one case of document.all (please see the first comment). We can see that in the == chart, null and undefined compares to true only with itself and each other: null == null is true, and null == undefined is true, etc, and nothing else. So when we use something == null, the only something that can give a true is null and undefined:

enter image description here

Even the TC39 is using it that way:

https://github.com/tc39/proposal-optional-chaining/blob/master/README.md

a?.b                          // undefined if `a` is null/undefined, `a.b` otherwise.
a == null ? undefined : a.b

However, I don't recommend using it in common daily coding. That's because, if the code a == null is read by other programmers, they may immediately change it to a === null and if the test cases are not able to catch it, then a subtle bug might be introduced in the system.

In an open source project where you have the ultimate decision for what goes in and what doesn't, then it can be used, with your code review and approval. Or, if you use it once or twice and then with proper comment up above to state what you are trying to do.

Otherwise, most other programmers may think if you really aim to compare just to null and not considering for undefined. If you write a === null || a === undefined, then most everybody knows exactly what you are trying to do.

A third side effect is, if you say a == null is identical to a === null || a === undefined, you could attract tons of users on Stack Overflow, downvoting on you, saying don't ever use == in JavaScript.

An interesting fact is, even Babel translate a?.b to compare with both null and undefined (void 0), instead of just using == null. Babel doesn't really have to, but maybe it does that so that when a programmer reads the compiled code, it is more clear.

But I don't know how many interviewers have asked me if the line if (a == null) is good, and when I said we should use ===, then I was viewed as just one step above greenhorn, because all the "pros" know that a == null is for checking whether a is null or undefined. So while maybe it is not good to actually use it in the code, it is good for testing if somebody is a pro.

nonopolarity
  • 130,775
  • 117
  • 415
  • 675
  • 2
    I'm the TC39 Champion for optional chaining: We use `== null` in explainer docs because it's easier to understand. They are **not** equivalent though. `== null` is the same as `=== null || === undefined || === document.all` (in browsers, node does not have a `document.all`). – Justin Mar 16 '20 at 19:35
  • 1
    @Justin So in all cases, they are the same except the case of `document.all`? `document.all` is like the "super" exception in JS as it is an object but `!!document.all` is false... so it is like something that can violate the law of physics – nonopolarity Mar 20 '20 at 08:55