Fundamentalsbeginner

Primitive vs Reference Types

The distinction between value types (numbers, strings, booleans) and reference types (objects, arrays, functions), and how it affects copying and comparison.

Primitives are copied by value. Objects are copied by reference. Almost every surprising assignment bug comes from that line.

A primitive is like handing someone a photocopy of a document — they can scribble on their copy without touching yours. A reference type is like handing someone the key to your apartment — anything they do inside changes the same apartment you both have access to.

Key Concepts

1
    let a = 1;
    let b = a;
    b = 2;
    console.log(a);        // 1  -- independent
2
    let o = { n: 1 };
    let p = o;
    p.n = 2;
    console.log(o.n);      // 2  -- the same object
3
The primitives: string, number, boolean, null, undefined, symbol, bigint. Everything else — objects, arrays, functions, dates — is a reference.
stringnumberbooleannullundefined
4
Which explains argument passing.
    function reassign(obj) { obj = { n: 99 }; }
    function mutate(obj)   { obj.n = 99; }
5
    const x = { n: 1 };
    reassign(x); console.log(x.n);   // 1  -- the parameter was rebound
    mutate(x);   console.log(x.n);   // 99 -- the object was changed
6
The parameter holds a copy of the reference. Reassigning it points the copy somewhere else and the caller is unaffected. Mutating through it changes the object both names point at.
7
And why two identical objects are not equal.
    {} === {}          // false -- two different objects
    [1] === [1]        // false
    1 === 1            // true  -- primitives compare by value
8
Copying is shallow by default.
    const orig = { a: 1, nested: { b: 2 } };
    const copy = { ...orig };
9
    copy.a = 99;          // orig.a is still 1      -- top level copied
    copy.nested.b = 99;   // orig.nested.b is 99    -- still shared
10
Spread and Object.assign copy one level. Nested objects remain the same objects, which is the bug that looks like the copy did not work.
Object.assign
11
For a genuine deep copy.
    structuredClone(orig)              // built in, handles cycles,
                                       // Map, Set, Date
    JSON.parse(JSON.stringify(orig))   // loses functions, undefined,
                                       // Date becomes a string, and
                                       // throws on cycles
12
structuredClone is the modern answer. The JSON round trip is everywhere in older code and quietly damages anything that is not plain data.
structuredClone
13
The practical habit. When a change appears in a place you did not touch, the two places are the same object. Checking that first is faster than reading the logic.
14
What the interviewer is probing.1. "What happens when you pass an object to a function and reassign the parameter?" Probing: copy semantics. Stalls: "The caller sees the new object." Moves up: the reference is copied, so mutating the object is visible but reassigning the parameter is not.
15
2. "Why does [1,2] === [1,2] return false?" Probing: identity versus value. Stalls: "They look the same." Moves up: each literal creates a new object and comparison is by reference, so only the same object is equal to itself.
16
3. "Which types are primitives?" Probing: the list. Stalls: "Numbers and strings." *Moves up:* string, number, boolean, null, undefined, symbol and bigint — everything else is an object.
17
4. "How do you copy an object safely?" Probing: shallow versus deep. Stalls: "Spread it." Moves up: spread and Object.assign are shallow, so nested objects stay shared; structuredClone handles deep copies.