JavaScript null vs undefined code examples shown in editor and console on laptop

Every JavaScript beginner meets the same confusing moment: your code prints undefined in one place and null in another, and they look like they mean the same thing. They do not. Understanding JavaScript null vs undefined, explained with examples, is one of those small investments that pays off every single day you write JavaScript, because these two values show up in function returns, object properties, API responses, and bug reports alike.

The short version: undefined means “this variable exists but nothing has been put in it yet,” while null means “someone deliberately put an empty value here.” That one-sentence distinction explains almost everything. The rest of this guide unpacks it with real code you can run, the comparison quirks that trip people up, and practical rules for which one to use in your own code.

In This Guide

What undefined Means in JavaScript

Handwritten notes comparing JavaScript null and undefined beside laptop console outputundefined is a primitive value that JavaScript assigns automatically when something has been declared but has no value yet. You rarely write undefined yourself — the language produces it for you in several everyday situations:

// 1. A declared variable with no assignment
let username;
console.log(username); // undefined

// 2. A function parameter that was not passed an argument
function greet(name) {
  console.log("Hello, " + name);
}
greet(); // Hello, undefined

// 3. A function with no return statement returns undefined
function doNothing() {}
console.log(doNothing()); // undefined

// 4. Accessing an object property that does not exist
const user = { name: "Priya" };
console.log(user.age); // undefined

// 5. An array slot that was never filled
const items = [10, 20];
console.log(items[5]); // undefined

Think of undefined as JavaScript’s way of saying “I looked, and there is nothing here yet.” It is the default, accidental empty — a placeholder the engine inserts when no value was ever provided.

What null Means in JavaScript

null is also a primitive value, but unlike undefined it never appears by accident. It only exists because a programmer deliberately wrote it. It means “this variable intentionally holds no value right now.”

// A search that found nothing returns null on purpose
let selectedUser = null;

// Later, when the user picks someone:
selectedUser = { name: "Arjun", id: 42 };

// Resetting back to "deliberately empty":
selectedUser = null;

This intentional emptiness is the whole point. When you see null in code, someone made a decision: this thing exists, it could hold a value, and right now it explicitly holds none. Common places you will meet it:

  • DOM methods: document.getElementById("missing-id") returns null when no element matches — the browser deliberately telling you “nothing found.”
  • JSON data from APIs: {"middleName": null} means the field exists but has no value, which is different from the field being absent entirely.
  • Clearing references: setting an object to null signals that it is done being used.

The MDN documentation on null and the MDN documentation on undefined are the authoritative references for the exact semantics.

Null vs Undefined: The Key Differences Side by Side

Aspect undefined null
Meaning Declared but never assigned a value Deliberately assigned as “no value”
Who creates it JavaScript itself, automatically The programmer, intentionally
typeof result "undefined" "object" (a famous historical quirk)
JSON representation Property is dropped: JSON.stringify({a: undefined}) gives "{}" Property is kept: JSON.stringify({a: null}) gives '{"a":null}'
In arithmetic Becomes NaN: undefined + 1 is NaN Becomes 0: null + 1 is 1
Default parameters Triggers the default: function f(x = 5) {}, f(undefined) uses 5 Does not trigger the default: f(null) passes null

Two rows in that table deserve emphasis because they cause real bugs. First, typeof null === "object" is a bug from the very first JavaScript implementation that was never fixed for backward-compatibility reasons — so never use typeof to detect null; compare with === null directly. Second, the JSON behavior means an API sending {"a": undefined} effectively sends {}, while {"a": null} explicitly sends an empty field — a meaningful difference when a backend distinguishes “field missing” from “field empty.”

How Each One Shows Up in Real Code

Let us trace both values through a realistic snippet — the kind of form-handling code beginners write when learning addEventListener:

const form = document.getElementById("signup-form");
const nicknameInput = document.getElementById("nickname");

form.addEventListener("submit", (event) => {
  event.preventDefault();

  // undefined: the input element exists, but the user typed nothing
  // and we never set a fallback — nickname is an empty string here,
  // but imagine we read a missing data attribute instead:
  const referral = nicknameInput.dataset.referral; // undefined (attribute absent)

  // null: we deliberately model "no referrer chosen yet"
  let referrer = null;
  if (referral) {
    referrer = referral;
  }

  console.log(typeof referral); // "undefined"
  console.log(referrer === null); // true
});

Notice the pattern: undefined arrived uninvited (the data attribute simply was not there), while null was a conscious modeling choice. When you later serialize this to send to a server, undefined fields vanish from the JSON while null fields arrive explicitly empty — which is exactly what most APIs expect.

Comparison Quirks: ==, ===, and typeof

This is where most beginner bugs live. JavaScript has two equality operators, and they treat null and undefined very differently:

console.log(null == undefined);  // true  (loose equality: both are "empty-ish")
console.log(null === undefined); // false (strict equality: different types)

console.log(typeof undefined);   // "undefined"
console.log(typeof null);        // "object"  (the historical quirk!)

The loose equality == considers null and undefined equal to each other (and to nothing else — null == 0 is false, undefined == false is false). This is actually useful: value == null is a concise way to check for either null or undefined in one test. Many style guides forbid == generally but explicitly allow this one case.

Strict equality === distinguishes them, which is what you want when the difference matters — for example, when a function treats “argument not passed” (undefined, use the default) differently from “argument explicitly cleared” (null, keep it empty):

function setAvatar(url) {
  if (url === undefined) {
    url = "default-avatar.png"; // not passed: use the default
  }
  // if url === null, the caller explicitly wants NO avatar — respect it
  renderAvatar(url);
}

setAvatar();        // uses default-avatar.png
setAvatar(null);    // renders with no avatar, as requested
setAvatar("me.png"); // renders me.png

The rule of thumb: default to === everywhere, and reach for == null only as a deliberate shorthand for “missing in either sense.”

Best Practices: When to Use Which

Now the practical question: in your code, which one should you write? Follow these conventions and your code will be predictable to every JavaScript developer who reads it:

  • Never assign undefined yourself. If you need an intentional empty value, use null. Writing let x = undefined destroys the useful signal that “undefined means the language put this here, not me.”
  • Use null for intentional emptiness. Initializing a variable that will hold an object later, representing “no result” from a search, clearing a reference — these are all null jobs.
  • Let undefined mean “not yet.” Unset options, missing function arguments, absent object properties — leave these as undefined and check for them with === undefined or the == null shorthand.
  • Be consistent within a codebase. The worst outcome is a project where half the functions return null for “not found” and the other half return undefined. Pick one convention for your APIs and document it.
  • Check existence before accessing properties. Both values throw TypeError: Cannot read properties of null (reading 'x') (or of undefined) when you access a property on them. Guard with an explicit check or use optional chaining from the next section.

Modern Tools: Optional Chaining and Nullish Coalescing

Modern JavaScript gives you two operators designed precisely for the null/undefined problem. They treat null and undefined as one category — “missing” — which is exactly right for defensive code.

Optional chaining (?.)

Instead of crashing on a missing nested property, ?. short-circuits to undefined:

const response = { data: null };

// Old way: crashes with TypeError
// console.log(response.data.user.name);

// Safe way: evaluates to undefined, no crash
console.log(response.data?.user?.name); // undefined

// Also works for function calls and array access
console.log(user.getName?.()); // undefined if getName does not exist
console.log(items?.[0]);       // undefined if items is null/undefined

Nullish coalescing (??)

?? provides a fallback only when the left side is null or undefined — unlike ||, which also triggers on 0, "", and false:

const timeout = config.timeout ?? 3000;

console.log(timeout); // 3000 if config.timeout is null or undefined
                      // but 0 if config.timeout is 0 (|| would wrongly give 3000)

This distinction matters in real interfaces: a volume slider set to 0 is a deliberate choice, not a missing value. Pairing ?. with ?? — for example const name = user?.profile?.name ?? "Guest" — handles almost every null/undefined situation in one readable line. If you are building interactive pages, our dark mode toggle guide shows these operators handling real user preferences in practice.

Frequently Asked Questions

Is null an object in JavaScript?

No, null is a primitive value, but typeof null returns "object" due to a bug in the original 1995 implementation that could never be fixed without breaking the web. Always test for null with value === null, never with typeof.

Why does my function return undefined when I forget return?

Every JavaScript function returns undefined by default if execution reaches the end without hitting a return statement. This is the language’s automatic-empty behavior, not an error — though it usually means you forgot to return the value you computed.

Should I check with == null or === undefined?

Use value == null when you want to catch both null and undefined in one check (the standard “is it missing?” test). Use value === undefined or value === null when the distinction between “never set” and “deliberately empty” matters to your logic.

What is the difference between null and undefined in JSON?

JSON.stringify drops properties whose value is undefined but keeps properties whose value is null. So {"a": null} transmits an explicit empty field, while {"a": undefined} transmits {}. APIs often treat these differently, so be deliberate about which one you send.

Can I use null and undefined interchangeably?

Technically your code will often work, but you should not. Keeping undefined for “not yet assigned” and null for “intentionally empty” gives every reader — including future you — a reliable signal about what the code means.

What does “Cannot read properties of undefined” mean?

You tried to access a property (like user.name) on something that is undefined or null. The fix is to find out why the variable is empty — trace where it was supposed to get its value — and guard the access with a check or optional chaining (?.) in the meantime.

Key Takeaways

  • undefined means “declared but never given a value” and is produced automatically by JavaScript; null means “deliberately empty” and is always assigned by a programmer.
  • null == undefined is true but null === undefined is false — use strict equality by default and the == null shorthand only deliberately.
  • typeof null returns "object" due to a historical bug; test for null with === null.
  • Never assign undefined yourself; use null for intentional emptiness and keep the two meanings distinct.
  • Optional chaining (?.) and nullish coalescing (??) safely handle both values — prefer ?? over || when 0 or "" are valid values.

Conclusion

JavaScript null vs undefined stops being confusing the moment you internalize the core distinction: undefined is JavaScript’s automatic “nothing here yet,” and null is your deliberate “nothing here on purpose.” Write null when you mean empty, never assign undefined by hand, compare with ===, and lean on ?. and ?? for safe access. With these habits, the two empties become a precise communication tool instead of a source of bugs.

Leave a Reply

Your email address will not be published. Required fields are marked *