0

I've always maintained the practice of checking if a value is undefined using

if (typeof x === 'undefined')

However, a colleague is suggesting that using if (x) { is better.

Is there any difference between these two methods from a computational point of view?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Oliver Kucharzewski
  • 2,523
  • 4
  • 27
  • 51
  • 10
    These are not equivalent (and also not inverses of each other). `if(x)` checks for [truthy values](//developer.mozilla.org/en/docs/Glossary/Truthy); the other one checks for `undefined`, specifically. But then, `if(x === undefined)` is easier. – Sebastian Simon Nov 17 '22 at 01:37
  • You should view this post: https://stackoverflow.com/questions/6604749/what-reason-is-there-to-use-null-instead-of-undefined-in-javascript has a detailed answers with the benefits of `undefined` – jtwalters Nov 17 '22 at 01:41
  • @jtwalters it's not relevant – zerkms Nov 17 '22 at 01:41
  • Depending on the context, for parameters, I tend to use `x == null` to cover both the use case of `null` and `undefined`. It ensures a boolean output and its cross-language is more descriptive and readable. – Jens Ingels Nov 17 '22 at 02:08
  • As @SebastianSimon got at, you should basically never use `typeof x === 'undefined'`. `x === undefined`, however, is a nice and specific check when you don’t need general falsiness. – Ry- Nov 17 '22 at 02:57

2 Answers2

4

There are at least two differences off the top of my mind:

  1. Checking the type as undefined only checks for undefined, unlike if(x), which checks for any truthy values (e.g. true, a non-empty string, a non-zero number, etc)
  2. You can perform typeof on non-existent variables, even in strict mode. You'll get a reference error if you never declared x and did if(x)

"use strict";

const a = undefined;
const b = "truthy value";

if(a) {
  console.log("a in if"); // never executes
}
if(typeof a !== "undefined") {
  console.log("a with typeof"); // never executes
}

if(b) {
  console.log("b in if"); // executes
}
if(typeof b === "undefined") {
  console.log("b with typeof"); // never executes
}


try {
  if(c) console.log("this should error");
} catch(e) {
  console.log("Can't access non-existent variable");
}

console.log("No error:", typeof c);

When should I use which one?

Generally:
Use if(x) when...

  • You're checking for a boolean
  • You're checking for (not) 0
  • You're checking for a non-empty empty string (probably use if(string.length) instead)
  • Checking the return value of a function (e.g. a function returns null when there's no result for a query or an object when there is (DOM functions like document.getElementById return null when no element with that ID exists))

Use if(typeof x !== "undefined") when...

  • You're checking whether an object key exists (if(typeof obj.key !== "undefined")) (the proper way as a commentator pointed out is with Object.hasOwn(obj, "key"))
  • You're checking whether a variable exists (not sure when or why you would do that though)
  • Checking whether an argument has been passed
  • Other uses like when you're writing an Express server and checking user-provided content
  • Something else I probably forgot...
code
  • 5,690
  • 4
  • 17
  • 39
  • Another important use case of `if(x)` is to check whether an object exists. Lots of functions return either an object or `null` (or either an object or `undefined`). Especially HTML elements. Key membership should be checked with [`Object.hasOwn(obj, "key")`](//developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn), not with `in`. The arguments use case is very useful indeed. – Sebastian Simon Nov 17 '22 at 02:06
  • @SebastianSimon right, I'll make the updates. – code Nov 17 '22 at 02:12
  • Hey @code - I just wanted to note that it seems that the following works: `let obj = {test1: "test1", test2: "test2"}; if (!obj.test3) { console.log('nice'); }` Is there any instance where this may fall short? – Oliver Kucharzewski Nov 17 '22 at 02:37
  • @OliverKucharzewski `if(x)` checks for falsy values. `undefined` is also a `falsy` values, so while it will not execute when something is undefined, neither will it when the value is `false`, `""`, or `null`. `obj.test3` is `undefined`, which coerces to false. When you flip that, it will be true. `if` will see `true`, which is why it executes. Hope that makes sense? – code Nov 17 '22 at 02:42
  • Thats completely fair, thanks @code :) – Oliver Kucharzewski Nov 17 '22 at 02:46
-1

Something that's useful to keep in mind is that Javascript is dynamically typed, even if it looks like it's just variables. There are a handful of types in JS, and Undefined (with caps) is one, and the only value it can hold is undefined. Think of it like saying you have the Number type and it only accepts 42. This is important to know because JS engines have to observe spec.

The Undefined type has exactly one value, called undefined. Any variable that has not been assigned a value has the value undefined.

There is a lot of variation in application code, but you can know that variables that have not been assigned are of type Undefined with value undefined and not something else. Next to Undefined is Null, which has a single value, null. Null, unlike Undefined, needs to be assigned.

In the spec you'll also the find the table for the result you get for each variable type.

You'll notice that Undefined has its own return value, as well as Boolean, but Null returns "object", which is reported to be a mistake in the original spec that we can't get rid of.

With types out of the way, we get to Boolean coercion, which is how if statements work out the condition. The spec has a table of cases that define when a value should be coerced into true or false.

You'll see that an if clause receives the Undefined type, it returns false. The same happens with Null. There are a few other cases that can also return false even if they are not Undefined or Null.

  1. The Number type with values 0, -0, NaN
  2. The String type with length 0 ("")
  3. The BigInt type with value 0

As others have already answered, applications of the spec come in a few different places. The reasons as for why typeof exists and there is an overlap with the falsey evaluation arise from how the JS engines handle values and perform coercion into Boolean.

OFRBG
  • 1,653
  • 14
  • 28