JavaScript
Programming
Web Development
Null vs Undefined
Coding Concepts

What is the difference between null and undefined in JavaScript?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

null and undefined both represent missing values in JavaScript, but they mean different things and behave differently in comparisons and APIs. Confusion between them leads to subtle bugs in validation, serialization, and conditional logic. A clear convention around both values makes code easier to reason about.

Core Meaning of Each Value

undefined usually means a value has not been assigned. JavaScript produces it automatically in common situations such as reading a missing object property or calling a function without a return statement.

null is an intentional empty value. Developers set null to say a value is known and explicitly absent.

javascript
1let a;
2console.log(a); // undefined
3
4const user = { name: 'Mina' };
5console.log(user.email); // undefined
6
7const selectedTeam = null;
8console.log(selectedTeam); // null

Use this mental model:

  • undefined is often implicit absence.
  • null is explicit absence.

Equality and Type Behavior

Both values are falsy, but equality results differ depending on operator choice. Loose equality treats them as equal to each other, while strict equality keeps them distinct.

javascript
1console.log(null == undefined);   // true
2console.log(null === undefined);  // false
3console.log(typeof undefined);    // "undefined"
4console.log(typeof null);         // "object" historical behavior

In production code, prefer strict equality. It avoids surprising coercions and communicates intent clearly.

Working with APIs and JSON

JSON can represent null, but it cannot represent undefined. During serialization, properties with undefined values are omitted, while null values are preserved.

javascript
1const payload = {
2  a: undefined,
3  b: null,
4  c: 42,
5};
6
7console.log(JSON.stringify(payload));
8// {"b":null,"c":42}

This matters in API contracts. If your backend expects a field to be present with an empty value, send null, not undefined.

Practical Patterns for Safer Code

Use nullish coalescing when you want defaults only for nullish values. This avoids overriding valid falsy values such as zero or empty string.

javascript
1function normalizeTimeout(ms) {
2  return ms ?? 5000;
3}
4
5console.log(normalizeTimeout(undefined)); // 5000
6console.log(normalizeTimeout(null));      // 5000
7console.log(normalizeTimeout(0));         // 0

For checks where either missing state is acceptable, compare once against null using loose equality in a very targeted way.

javascript
1function isMissing(value) {
2  return value == null; // true for null and undefined only
3}
4
5console.log(isMissing(undefined)); // true
6console.log(isMissing(null));      // true
7console.log(isMissing(''));        // false

Use this intentionally and keep it localized so readers know it is deliberate.

Choosing a Team Convention

A practical team standard is:

  • Use undefined for internal optional values not set yet.
  • Use null in external contracts when explicit emptiness should be transmitted.
  • Use strict equality by default.
  • Use value == null only in helper utilities for combined missing checks.

This keeps behavior consistent across frontend code, Node services, and tests.

Interop with TypeScript and Validation Layers

In mixed JavaScript and TypeScript projects, nullish policy is easiest to maintain when runtime validation mirrors type definitions. For example, if an API field can be absent but not intentionally empty, treat undefined as allowed and reject null at the boundary. If explicit empty is allowed, include null in the contract and handle it intentionally.

javascript
1function readDisplayName(input) {
2  if (input === undefined) return 'guest';
3  if (input === null) return 'anonymous';
4  return String(input);
5}
6
7console.log(readDisplayName(undefined));
8console.log(readDisplayName(null));
9console.log(readDisplayName('Kai'));

This style keeps business behavior explicit and prevents ambiguous missing-value semantics from leaking into UI logic.

Debugging Strategy for Nullish Bugs

When nullish bugs appear, log both value and type at boundaries, then follow the value through transformations. Many issues come from one module defaulting to undefined while another expects null.

javascript
1function debugValue(label, value) {
2  console.log(label, value, typeof value, value === null, value === undefined);
3}
4
5debugValue('api field', undefined);
6debugValue('db field', null);

Keeping this debugging helper in test code can reduce time spent on hard-to-reproduce conditional failures.

Common Pitfalls

  • Treating null and undefined as fully interchangeable in all contexts.
  • Using loose equality everywhere and getting unexpected coercion behavior.
  • Sending undefined in payloads and assuming backend receives the field.
  • Overwriting valid falsy values with defaults by using logical OR.
  • Mixing conventions across modules and making API behavior inconsistent.

Summary

  • undefined usually means not assigned.
  • null means explicitly empty.
  • Strict equality distinguishes them and should be default.
  • JSON keeps null but omits undefined properties.
  • Establish one project convention and apply it consistently.

Course illustration
Course illustration

All Rights Reserved.