Difference Between Null, Undefined, and Undeclared in JavaScript
In JavaScript, null represents an intentional absence of value, undefined indicates a declared variable lacks initialization, and undeclared variables throw ReferenceErrors because they never entered any lexical scope.
Understanding how JavaScript handles absence of value is fundamental to debugging and writing defensive code. According to the h5bp/Front-end-Developer-Interview-Questions source code, this distinction appears as a core interview question in src/questions/javascript-questions.md, testing whether developers recognize how the engine treats different uninitialized states. When you encounter null, undefined, or undeclared identifiers, each represents a distinct scenario with specific implications for type checking and error handling.
What Is null in JavaScript?
null represents the intentional absence of any object value. Developers must explicitly assign null to variables to signal "no value" or an empty state, distinguishing it from uninitialized variables.
When read, null returns the value null with a type of object—a historical quirk in JavaScript's type system. As documented in the interview questions repository, this makes null ideal for signaling that a variable exists but currently holds no data, such as when awaiting asynchronous input or intentionally clearing an object reference.
// Explicit empty assignment
let userInput = null;
if (userInput === null) {
console.log('Waiting for data...');
}
Understanding undefined in JavaScript
undefined represents the default value for declared variables that lack initialization. The JavaScript engine automatically assigns this value when variables are declared without initializers, when functions execute without returning values, or when accessing non-existent object properties.
Unlike null, which requires explicit assignment, undefined indicates the engine has reserved the identifier but no value has been stored. The typeof operator returns "undefined" for these values, making them detectable without risking runtime errors.
// Declared but not initialized
let config;
console.log(config); // undefined
// Function without return
function getData() {
// no return statement
}
console.log(getData()); // undefined
Undeclared Variables and ReferenceErrors
An undeclared variable refers to an identifier that never appeared in any lexical environment—no var, let, const, function, or class declaration exists for that name. As noted in src/translations/_template/README.md, this represents a programming error where code attempts to use a variable that was never defined.
Unlike null and undefined, which are actual values you can compare, reading an undeclared variable causes the engine to throw a ReferenceError at runtime, immediately stopping execution.
// Attempting to read undeclared variable
console.log(missingVar); // ReferenceError: missingVar is not defined
Safe Detection Patterns
Because these three states behave differently, you must use specific techniques to check for each without triggering errors:
- Checking for
null: Use strict equality (=== null) to detect intentional emptiness - Checking for
undefined: Use strict equality (=== undefined) or rely on the fact thattypeofreturns"undefined" - Checking for undeclared: Use
typeof, which returns"undefined"for undeclared identifiers without throwing a ReferenceError
// 1. Null check
if (myVar === null) {
console.log('Explicitly empty');
}
// 2. Undefined check
if (myVar === undefined) {
console.log('Never initialized');
}
// 3. Undeclared check (safe)
if (typeof maybeMissing === 'undefined') {
console.log('Variable was never declared');
}
Summary
nullis an explicit developer assignment indicating intentional absence of value, withtypeofreturning"object"undefinedis the automatic default for declared but uninitialized variables, withtypeofreturning"undefined"- Undeclared variables never entered any lexical scope and throw
ReferenceErrorwhen accessed - Use
typeof variable === 'undefined'to safely check for undeclared variables without runtime errors - Use strict equality (
===) to distinguish betweennullandundefinedin conditional logic
Frequently Asked Questions
Why does typeof null return "object" in JavaScript?
This behavior is a historical quirk in the JavaScript language specification that has persisted since the language's initial implementation. When processing null, the engine's binary representation was interpreted as an object pointer, causing typeof to return "object" rather than "null". As documented in the h5bp interview questions, this cannot be changed without breaking backward compatibility with existing web applications, despite null being a primitive value that represents "no object."
How do I check if a variable is undeclared without throwing a ReferenceError?
Use the typeof operator, which safely returns "undefined" for undeclared identifiers without throwing an error. Unlike direct variable access—which immediately triggers a ReferenceError for undeclared names—typeof checks the lexical environment without attempting to read the value. For example: if (typeof myVar === 'undefined') handles both undeclared variables and variables explicitly set to undefined without crashing your script.
What is the difference between null and undefined?
null represents an intentional absence of value assigned by developers to indicate "no value" or empty state, while undefined represents the default absence of initialization automatically assigned by the engine. You can assign null to clear an object reference, whereas undefined typically indicates a variable was declared but never given a value, a function lacked a return statement, or an object property does not exist. The strict equality operator (===) distinguishes them, as null === undefined evaluates to false.
When should I use null versus leaving a variable undefined?
Assign null when you want to explicitly signal that a variable is intentionally empty or will receive a value later, such as resetting an object reference or initializing a placeholder for asynchronous data. Allow undefined to remain as the natural state for uninitialized declarations or missing properties, letting the engine indicate that initialization has not occurred. Never leave variables undeclared, as this indicates a bug rather than a valid programming state.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →