Type System
JavaScript has just two large families of values — primitives and objects — and almost every type trap grows from the difference between them. There are seven primitives (string, number, boolean, null, undefined, bigint, symbol): they are immutable and copied by value. Everything else is an object: mutable and copied by reference. This distinction explains why a const object can have its properties changed, why a mutation is visible through two variables, but a reassignment is not.
On top of that sit the subtleties: typeof null returns 'object' (a long-standing language bug), NaN is not equal to itself, and a primitive suddenly has methods — because the engine briefly wraps it in an object. Each layer below dissects one such mechanism.
Topic map
- Primitive types — the seven primitives, what makes a value primitive, and how it differs from an object.
- The typeof operator — which strings
typeofreturns and why fornullit is'object'. - null vs undefined — "not assigned" versus an explicit "no value", and how they behave under comparison and coercion.
- Value vs reference — why primitives are copied but objects are shared, and what "pass by sharing" means.
- Wrapper objects — how a primitive gets methods through a temporary
String/Number/Booleanwrapper. - NaN — what this value is, why it is not equal to itself, and how to test it with
Number.isNaN. - Immutability — the immutability of primitives, what
constactually protects, and the role ofObject.freeze.
Common traps
| Mistake | Consequence |
|---|---|
Treating null as an object because of typeof null | Wrong type check — it is a long-standing bug, not a type |
Testing NaN with x === NaN | Always false — NaN is not equal to itself |
Using global isNaN instead of Number.isNaN | False positives — the global one coerces its argument to a number |
Thinking const makes an object immutable | const blocks only rebinding; properties still change |
| Expecting an object change in a function to be invisible outside | The reference is shared — the mutation is visible to all holders |
Accessing a property on null/undefined | TypeError — they have no wrapper object |
Interview relevance
The type system is asked to weed out a candidate who knows the syntax but not the value model. The answer "null is when a variable was not assigned anything" already loses: that is exactly undefined. A strong answer separates the two families (primitive/object) and explains behavior through them.
Typical checks:
- How many primitives there are and what makes a value primitive.
- The difference between
nullandundefinedbytypeof, comparison, and coercion. - Value vs reference — what gets mutated and what gets copied.
- Why
NaN !== NaNand how to test it; whatconstprotects.
Common wrong answer: "const makes the value immutable". In fact const blocks only rebinding the name; a const object's properties change freely, and shallow freezing is what Object.freeze provides.