ESC

Type to search the knowledge base.

null vs undefined

When JS uses undefined vs null, equality traps, defaults, JSON gaps, and how to choose one intentionally in APIs.

beginner3 min read
  • javascript
  • null-vs

Both mean “no value,” but they are not the same type and the language treats them differently. Interviews love == vs ===, optional params, and “what does missing JSON key become?”

Definitions

undefined null
Type 'undefined' 'object' (legacy bug)
Who sets it Language / missing things Usually you (or APIs)
Meaning Not initialized / absent Intentional empty
let x;
x; // undefined — declared, not assigned

function f(a) {
  return a; // call f() → a is undefined
}

const o = {};
o.missing; // undefined

const u = { name: null }; // explicit empty name

Equality

null == undefined;  // true  (loose)
null === undefined; // false
null == 0;          // false
undefined == 0;     // false

Use === unless you deliberately want “nullish” with == null:

if (value == null) {
  // true for null OR undefined
}
// same intent:
if (value === null || value === undefined) {}

Prefer ?? / optional chaining over == null when assigning defaults:

const port = config.port ?? 3000; // only null/undefined → 3000

|| also replaces 0 and '' — usually wrong for numeric defaults.

JSON and the wire

JSON.stringify({ a: undefined, b: null });
// '{"b":null}'  — undefined keys are dropped on objects

JSON.stringify([1, undefined, null]);
// '[1,null,null]' — array holes become null in JSON

JSON.parse never produces undefined as a value; absence is missing keys.

typeof traps

typeof undefined; // 'undefined'
typeof null;      // 'object'  ← memorize

Never use typeof x === 'object' alone to mean “plain object”; exclude null.

API design choice

Convention that scales:

  • undefined: property omitted, param not passed, “use default.”
  • null: field exists, value is explicitly empty (DB NULL, cleared form field).
// PATCH body: omit = leave unchanged; null = clear
function patchUser(id, { name, bio }) {
  const body = {};
  if (name !== undefined) body.name = name;
  if (bio !== undefined) body.bio = bio; // bio: null clears
  return fetch(`/users/${id}`, {
    method: 'PATCH',
    body: JSON.stringify(body),
  });
}

Defaults and parameters

function greet(name = 'world') {
  // default only if name === undefined (not null!)
  return `hi ${name}`;
}
greet();         // hi world
greet(undefined);// hi world
greet(null);     // hi null

Interview answer (out loud)

“undefined means missing or uninitialized — the language produces it for missing args and properties. null is an intentional empty object value. They’re loosely equal but not strictly. Prefer ===, use ?? for nullish defaults, and remember typeof null === 'object' and that JSON drops undefined object keys.”

Destructuring defaults

const { name = 'anon' } = {}; // name is 'anon' (missing → undefined → default)
const { name: n = 'anon' } = { name: null }; // n is null — default skipped

Same rule as function parameter defaults: only undefined triggers them.

void 0

void 0 === undefined; // true
// historical: protect against undefined being shadowed as a variable in sloppy mode

Modern modules make shadowing undefined a non-issue; still appears in compiled output sometimes.

Further reading

Related guides