ECMAScript has eight language types: Undefined, Null, Boolean, String, Symbol, Number, BigInt, and Object. The first seven are primitive values; every member of the eighth, Object, is an object. Functions, arrays, dates, maps and class instances are all just objects.
What separates the two groups:
- Primitives are immutable. You can reassign a variable that holds a string, but you can't change the string itself. Methods like
toUpperCase()return a new value. - Primitives compare by value, objects by identity.
'a' === 'a'istrue;{} === {}isfalse, because each literal creates a new object. - Objects are collections of properties, each either a data property or an accessor property. Primitives have no properties of their own;
'abc'.lengthworks through a temporary wrapper (see the primitive-wrappers question).
Two types are easy to blur. undefined is what a variable holds before assignment; null is the explicit "no value" you assign. Number is an IEEE 754 double and BigInt is an arbitrary-precision integer, so they're different types and don't mix in arithmetic (1n + 1 throws).
typeof is not the type list. It returns eight strings, but they don't line up with the eight types: typeof null is "object", and callable objects report "function" although Function isn't a separate type.