Null vs. Undefined
Developers coming from other languages (like Python with None or Go with nil) might expect a single concept for “nothing.” JavaScript uniquely features two distinct values for the absence of data: undefined and null.
The Difference
undefined: Represents a variable that has been declared but has not been assigned a value. It is the default state of uninitialized data. In simpler terms, it’s “completely nothing.”null: Represents an intentional absence of any object value. It means the variable exists, and you have explicitly set it to be empty. In simpler terms, it’s “purposefully nothing.”
// Default state
let myName;
console.log(myName); // undefined
// Intentional emptiness
let myAddress = null;
console.log(myAddress); // null
The “Object” Quirk
Due to a historical bug in JavaScript’s original implementation that cannot be fixed without breaking millions of older websites, checking the type of null returns "object".
console.log(typeof null); // "object"
Despite this behavior, null is its own distinct primitive type in the ECMAScript specification.
Best Practices
In most applications, null and undefined behave similarly in conditional logic (both are “falsy”). However, consistency is key. Many developers treat undefined as the default empty state for variables and function returns, reserving null for specific cases where they need to explicitly reset an object or adhere to strict external API requirements.
Practical Example
A strict engineering standard might require that uninitialized metrics be explicitly set to null to differentiate them from variables that were accidentally skipped during initialization.
// Explicitly assigning null to indicate the data is intentionally blank right now
let sentMessages = null;
let deliveredMessages = null;
let failedMessages = null;
// The system can now strictly check if the values are intentionally empty
console.log("Sent is null:", sentMessages === null); // true
console.log("Delivered is null:", deliveredMessages === null); // true
console.log("Failed is null:", failedMessages === null); // true