4

Is it acceptable to use type coercion (== instead of ===) to check for undefined/null?

What are the downsides? Is there a better way to check for undefined/null?

Clarification: I am looking for a statement that will check for both undefined and null.

test(null);
test(undefined);

function test(myVar) {
    if (myVar != undefined) {
        alert('never gets called')
    }
}
user2954463
  • 2,362
  • 2
  • 23
  • 37

3 Answers3

5

I'm going to attempt to address this question as objectively as possible, but it deals with some mushy "best practices" opinion stuff that can trigger people to forget that there's more than one way to do things.

Is it acceptable to use type coercion (== instead of ===) to check for undefined/null?

It's acceptable to write code however you see fit regardless of anyone who tells you otherwise. Including me.

That's not really helpful here, so let me expand on that a bit, and I'll let you decide how you feel about it.

Code is a tool that can be used to solve problems, and == is a tool within JavaScript code to solve a specific problem. It has a well-defined algorithm which it follows for checking a type of equality between two parameters.

===, on the other hand, is a different tool that solves a different, specific problem. It also has a well-defined algorithm which it follows for checking a type of equality between two parameters.

If one tool or the other is appropriate for your use-case, then you shouldn't hesitate to use the tool.

If you need a hammer, use a hammer.

But if all you have is a hammer, then everything looks like a nail, and this is the core issue with ==. Developers coming from other languages often aren't aware of how == works and use it when === would be appropriate.

In fact, most use cases are such that === should be preferred over ==, but as you've asked in your question: that's not true in this instance.

What are the downsides?

If you relax your standards for === and allow developers to use == you may very well get bitten by misuse of ==, which is why sticking religiously to === may be acceptable to some, and seem foolish to others.

if (val === null || val === undefined) {...

is not particularly difficult to write, and is very explicit about intent.

Alternatively,

if (val == null) {...

is much more concise, and not difficult to understand either.

Is there a better way to check for undefined/null?

"better" is subjective, but I'm going to say, "no" anyway because I'm not aware of any that improve the situation in any meaningful way.

At this point I will also note that there are other checks that could be performed instead of null/undefined. Truthy/falsey checks are common, but they are another tool used to solve yet another specific problem:

if (!val) {...

is much more concise than either of the previous options, however it comes with the baggage of swallowing other falsey values.


Additional notes on enforcement via linting:

If you follow the strictness of Crockford's JSLint, == is never tolerated, in the understanding that a tool that's "sometimes useful" but "mostly dangerous" isn't worth the risk.

ESLint, on the other hand, allows for a more liberal interpretation of the rule by providing an option to allow null as a specific exception.

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
4

== undefined and == null are both equivalent to checking if the value is either undefined or null, and nothing else.

As for "acceptable", it depends on who is looking at the code, and whether your linter is configured to ignore this special case.

I can tell you for sure that some minifiers already do this optimisation for you.

Brian
  • 7,394
  • 3
  • 25
  • 46
  • If you want to test whether a variable is `undefined` then you should use `typeof` instead of testing directly. It's just good practice. – Aadit M Shah Sep 20 '16 at 18:43
  • Correct, to check if it is *exactly* null or *exactly* undefined, the author seems to already know how to do the right thing: `===`. – Brian Sep 20 '16 at 18:47
  • Because if the variable you're testing was never declared then you'd get a `ReferenceError`: http://stackoverflow.com/a/2703122/783743 – Aadit M Shah Sep 20 '16 at 18:47
  • 4
    @qxz I think older JavaScript interpreters allow you to change the value of `undefined` (e.g., by doing `undefined = true`), in which case comparing against `undefined` directly would not work as intended, but doing a typeof check would. Also, `typeof` also handles the case where a variable is *not defined* without causing exceptions. – Frxstrem Sep 20 '16 at 18:47
2

The ideal way to test for undefined is using typeof. Note you only need to test them separately if you care about a difference between undefined and null:

test(null);
test(undefined);

function test(myVar) {
    if (typeof myVar === "undefined") {
        // its undefined
    }
    if (myVar === null) {
        // its null
    }
}

If you don't care if its undefined/null, then just do:

test(null);
test(undefined);

function test(myVar) {
    if (!myVar) {
        // its undefined or null, dunno which, don't care!
    }
}
  • 1
    You need `myVar == null` (or `myVar == undefined`), not `!myVar`; the latter will also accept `0`, `''`, `false` and `NaN`... – Frxstrem Sep 20 '16 at 18:44
  • 2nd snippet: `undefined`, `null`, `0`, or anything else falsey – qxz Sep 20 '16 at 18:44
  • Note: the second example will swallow some things you might not intend, such as `0` and `NaN`. If this is undesired, go with the first example. –  Sep 20 '16 at 18:44
  • @Amy So if I wanted to check for both null and undefined at once, would I do `if (typeof myVar === "undefined" || myVar === null)` ? – user2954463 Sep 20 '16 at 18:47