Fundamentalsintermediate
Symbol and BigInt Primitives
Two newer primitive types: Symbol for guaranteed-unique property keys, and BigInt for integers beyond Number's safe range.
Two primitives added later, each solving a specific problem.
A Symbol is like a one-of-a-kind serial number stamped on an item — even if two items have the same product name, their serial numbers are guaranteed to be different. BigInt is like switching from a calculator with a fixed digit display to a full ledger book — you trade a bit of convenience for the ability to write numbers of any size without rounding.
Key Concepts
1
A symbol is a guaranteed-unique value.
const a = Symbol('id');
const b = Symbol('id');
a === b // false -- the string is only a label2
Which makes it safe as a property key.
const HIDDEN = Symbol('internal');
obj[HIDDEN] = 'data';3
Object.keys(obj) // does not include it
JSON.stringify(obj) // does not include it
for (const k in obj) // does not include it4
So a library can attach data to an object a consumer owns, with no chance of colliding with their keys and
without it appearing in their serialisation.
5
Well-known symbols hook into language behaviour.
Symbol.iterator makes an object usable in for...of
Symbol.asyncIterator for await...of
Symbol.toPrimitive controls coercion
Symbol.toStringTag what Object.prototype.toString reports6
obj[Symbol.iterator] = function* () { yield 1; yield 2; };
[...obj] // [1, 2]7
That is how a custom object becomes iterable — the reason for...of works on arrays, strings, Maps and
Sets is that they all define it.
for...of
8
Symbol.for uses a global registry, for the rare case where two separate pieces of code need the same
symbol.
Symbol.for
9
BigInt is for integers beyond Number's safe range.
Number.MAX_SAFE_INTEGER // 9007199254740991
9007199254740993n // exact, as a BigIntNumber
10
const big = 123456789012345678901234567890n;
BigInt('123') // from a string11
It does not mix with Number.
1n + 1 // TypeError
1n + BigInt(1) // 2n
1n == 1 // true -- loose equality coerces
1n === 1 // false12
The refusal is deliberate: silently converting would lose precision, which is the thing BigInt exists to
prevent.
13
Where it is actually needed. Large database ids, cryptographic values, high-precision timestamps, and
anything beyond 2^53. For ordinary arithmetic it is slower and unnecessary.
14
And the practical note. JSON.stringify throws on a BigInt. Serialising one means converting it to a
string deliberately, which is also why APIs send large ids as strings in the first place.
JSON.stringify
15
What the interviewer is probing.1. "What is a Symbol for?" Probing: the purpose. Stalls: "A unique string." Moves up: a
unique property key that cannot collide, used for metadata on objects and for protocols like
Symbol.iterator.
16
2. "Can you mix BigInt and Number in arithmetic?" Probing: the rule. Stalls: "Yes." *Moves
up:* no — it throws TypeError; convert explicitly, accepting the precision loss when going to
Number.
17
3. "Where would you actually use BigInt?" Probing: the use case. Stalls: "Large maths."
Moves up: IDs beyond 2^53, like Twitter snowflake ids or database bigints, where a Number would
silently lose precision.
18
4. "Are symbol keys returned by Object.keys?" Probing: enumeration. Stalls: "Yes." *Moves
up:* no — they are skipped by Object.keys and JSON.stringify, which is what makes them suitable for
hidden metadata.