Why does the typeof operator report a null value as an object?
The honest answer is that it is a bug from the very first implementation of JavaScript, and it was never fixed because fixing it would break working code all over the web. The language specification now requires the behaviour, so it is a quirk that is baked into the standard.
console.log(typeof null); // 'object'
console.log(typeof {}); // 'object'
console.log(typeof []); // 'object'
console.log(typeof function () {}); // 'function'
// The reliable check is a strict comparison.
function isNull(value) {
return value === null;
}
console.log(isNull(null)); // true
console.log(isNull({})); // false
console.log(isNull(undefined)); // false
The historical reason comes from how the first JavaScript engines stored values inside the computer. Every value carried a type tag, and an object was marked by setting one low bit in that tag, which said "this is an object and not a simple value". The null pointer was a special value that lived in the same part of memory, so it picked up the same object marker by accident. Arrays and functions later moved into their own categories, but null stayed exactly where it was.
The behaviour was noticed early and reported as a risk to compatibility. The response from the standards body was that the danger of breaking sites was bigger than the benefit of being correct, and that a future major revision might sort it out. That revision has never arrived.
The practical consequence is that typeof is useless as a way to detect null. Any code of the form if (typeof value === 'object') will treat null as an object, and then it will crash when it tries to read a property from it. Use a strict equality comparison instead, because it is exact and it never changes the type of what it compares.