Detailed explanation
In JavaScript, undefined and null are distinct primitive values that both represent absence, but usually communicate different intentions. undefined commonly means that no value has been supplied or produced; null conventionally means that a value is intentionally absent. For example, `let a;` initialises a to undefined, while `const b = null;` explicitly records an empty value. This distinction helps developers design predictable function contracts and interpret data from objects, APIs, and browser methods.
JavaScript produces undefined when you read a missing object property, omit a function argument, call a function that finishes without returning a value, or read an array index with no element. A bare `return;` also returns undefined. null must come from an explicit value supplied by code or an API: for example, `document.querySelector()` returns null when no element matches. However, reading an undeclared identifier normally throws ReferenceError rather than returning undefined. Also, undefined can be assigned explicitly, so it does not prove that a value was never set.
Each value has its own primitive type, but `typeof null` returns `"object"` because of a historical compatibility quirk; `typeof undefined` returns `"undefined"`. null is not actually an object. Loose equality specially treats them as equal: `null == undefined` is true, whereas `null === undefined` is false. Numeric conversion also differs: `Number(null)` is 0, but `Number(undefined)` is NaN, making `null + 1` equal 1 and `undefined + 1` equal NaN. Interviewers often check whether candidates can explain these results rather than merely memorise them.
These differences affect defaults and serialisation. Parameter defaults and destructuring defaults apply to undefined, not null. `JSON.stringify({a: undefined, b: null})` produces `'{"b":null}'`; undefined array entries and array holes become null. Optional chaining stops on either null or undefined and returns undefined, while nullish coalescing supplies a fallback for either value without replacing 0, false, or an empty string. A useful convention is to reserve null for intentional emptiness, but avoiding explicit undefined assignments is a team choice, not a language rule.
Key points to remember
- undefined usually indicates an unsupplied value; null conventionally indicates intentional absence.
- Both are primitives, despite typeof null returning "object".
- null == undefined is true; null === undefined is false.
- Parameter and destructuring defaults apply only to undefined, not null.
- ?. and ?? handle both null and undefined; || also treats other falsy values as absent.
Common mistakes candidates make
- Assuming an undeclared variable evaluates to undefined instead of normally throwing ReferenceError.
- Calling null an object because typeof null returns "object".
- Expecting null to activate a default parameter, or using || when valid values include 0, false, or "".
Likely follow-up questions
How do you check whether a value is either null or undefined?
Use `value === null || value === undefined` for an explicit check. The deliberate shorthand `value == null` also matches both in ordinary application code.
How can you distinguish a missing property from a property explicitly set to undefined?
Use `Object.hasOwn(obj, 'key')` to check whether the object itself contains that property. Reading `obj.key` alone returns undefined in both cases, assuming no inherited property supplies a value.
What happens when undefined and null are passed directly to JSON.stringify?
`JSON.stringify(undefined)` returns the JavaScript value undefined, whereas `JSON.stringify(null)` returns the string `"null"`. Within objects, undefined properties are omitted; within arrays, undefined entries become null.
Interview tip: Start with the difference in intent, show one example of each, and then explain strict equality, defaults, and nullish coalescing.
