undefined vs null
The ultimate bikeshed - undefined
vs null
.
TLDR for my take:
- For anyone who does not subject themselves to writing JavaScript, the distinction is pretty clear and obvious.
- In JavaScript,
null
is an undesirable relic, generally acting as a less usefulundefined
.
Colloquially / semantically
The way this is supposed to work is pretty simple:
undefined
means this value has not been set yetnull
means this value has been explicitly set to nothing
That's it.
In JavaScript, generally the two are interchangable for most use-cases.
They are both:
- Considered falsy.
- Not strictly equal to eachother. That is,
null !== undefined
. - Not strictly equal to any other primitive. That is,
typeof null !== typeof string
, etc.
TypeScript optional types
Optional properties are considered T | undefined
.
type Server = {
port?: number; // number | undefined
name: string;
};
const server: Server = {
// Error! null is not assignable to type number | undefined
port: null,
name: "haha hehe",
};
Note
This is subject to exactOptionalPropertyTypes.
Object destructuring
Any key set to undefined
will be overridden by default values when destructuring. null
will not be.
const open = ({ port = 8080 } = {}) => {
console.log(`Opening on ${port}`);
server.listen(port);
};
open(); // Opening on 8080
open({ port: undefined }); // Opening on 8080
open({ port: null }); // Opening on null
Variable declarations
Any unassigned variable is considered undefined
.
// undefined
let fruit;
For a variable to be null
, it must be explicitly set. No implicit behaviour will set a value to null
.
// Guess there's no fruit left. 😢
const fruit = null;
typeof
The typeof
any primitive is generally that primitive itself.
typeof "string"; // 'string'
typeof 0; // 'number'
typeof undefined; // 'undefined'
typeof Symbol(); // 'symbol'
However, typeof null === "object"
.
This is incorrect, and is considered a bug, one which is never planned to be fixed.
Nullish coalescing
For the purposes of the nullish coalescing operator (??
), they are both interchangable.
null ?? "a"; // "a"
undefined ?? "b"; // "b"
// NaN doesn't share these properties.
NaN ?? "c"; // NaN
For the optional chaining operator (?.
), expressions are always short-circuited to undefined
, not null
.
It doesn't matter if the left-hand side of the operator is null
or undefined
, it will short circuit to undefined
.
const store = {
shelves: null,
};
// undefined
const fruit = store?.shelves?.fruit;
Type coersion
Strangely, null
is considered 0
when type-converted into a number. undefined
is (more correctly, imho) considered NaN
.
null + 1; // 1
undefined + 1; // NaN