AceDevHub
Runtime & SyntaxFree

Data Types and typeof

Learn JavaScript's primitive and reference types, how typeof works, and the null vs object typeof quirk every interview tests.

All numbers are IEEE 754 double-precision floats. Integers beyond Number.MAX_SAFE_INTEGER lose exactness — that is why bigint exists for large IDs and crypto math. Floating-point means 0.1 + 0.2 !== 0.3 is expected, not a engine bug. Financial apps often store cents as integers or use decimal libraries instead of raw floats.

BeginnerFreeTypes

JavaScript values are either primitive (immutable, compared by value) or object (mutable, compared by reference). When you pass a number to a function, the function gets a copy of the bits. When you pass an object, the function gets a copy of the pointer — both pointers aim at the same heap object. That is why mutating function arguments can surprise newcomers and why React warns about mutating state directly.

Two families: primitives and objects

JavaScript values are either primitive (immutable, stored by value) or object (mutable, stored by reference). This distinction drives equality, copying, and function behavior.

CategoryTypestypeof result
Primitivestring, number, boolean, undefined, symbol, biginttypeof per type
Special primitivenulltypeof null → "object" (historical bug)
ReferenceObject, Array, Function, Date, …typeof → "object" or "function"

Primitives — immutable values

There are seven primitive types: string, number, bigint, boolean, undefined, symbol, and null. Everything else — plain objects, arrays, functions, dates, maps — is an object under the hood. typeof is a quick runtime check, not a perfect classifier: typeof null returns "object" for historical reasons, and typeof [] also returns "object" even though arrays behave differently in practice.

primitives.js
Loading editor…
Outputconsole
10 20

Objects — reference semantics

Primitives live as actual values in the variable slot (or on the stack in engine internals). When you copy a primitive, you duplicate the value. Strings look like objects because you can call .toUpperCase(), but strings themselves are immutable primitives — methods return new strings rather than mutating in place.

references.js
Loading editor…
Outputconsole
2
object

typeof operator

Objects live on the heap; variables hold references (think "address") to that heap location. Assigning with = copies the reference, not the object structure. Two empty arrays [] === [] is false because each literal creates a new object. To compare contents you need explicit logic — loop, JSON.stringify with caveats, or a utility like structuredClone plus deep equal.

typeof-examples.js
Loading editor…
Outputconsole
string
number
boolean
undefined
symbol
bigint
object
object
object
function

undefined vs null

typeof returns a string label for the operand's type. It is fast and safe for undefined checks on global names. It fails for null detection and cannot distinguish arrays from plain objects. Production code combines typeof with Array.isArray, value === null, and Number.isNaN instead of trusting typeof alone.

undefined means no value assigned — a parameter omitted, a let without initializer, or a missing object property. The engine uses undefined automatically. null means intentionally empty — a developer chose to signal "we know this field exists but has no value yet." APIs often return null for "not found" and undefined for "field not included." JSON.stringify drops undefined keys but keeps null, which matters for HTTP APIs.

null-vs-undefined.js
Loading editor…
Outputconsole
Hello guest
undefined
null

Number gotchas worth knowing early

The example below demonstrates "Number gotchas worth knowing early" in runnable form. Read the comment lines first — they map each step to the mental model from earlier sections, then trace execution top to bottom as the engine would.

number-gotchas.js
Loading editor…
Outputconsole
0.30000000000000004
false
9007199254740991
number
true
  1. 1Primitives copy by value; objects copy by reference
  2. 2typeof null returns "object" — use === null instead
  3. 3Use Array.isArray and Number.isNaN for precise checks
  4. 4Next lesson: operators, coercion, and why 0 == "0" is true