These questions ask you to classify values, read type checks, and predict comparisons or numeric operations. A reliable approach is to name the value category first, then apply the exact operation instead of relying on how the value looks.
Classify first, then apply the operation
Begin with the seven primitive families. Anything outside that list, including an array or callable function, belongs to the object side of the model. Then keep the value model separate from an operator label: typeof null produces the string object, while typeof Math.max produces function. NaN remains in the Number family even though its spelling may look like a separate category; do not invent a new primitive family from a value's spelling.
| Signal | Decision procedure and small example |
|---|---|
| A primitive is reassigned | Separate the binding from the value. After let word = "oak" and word = "elm", the binding points elsewhere; the earlier string was not altered. |
| Two objects are compared | Ask whether both expressions reach the same object. If a = [4] and b = [4], a === b is false; matching contents do not create shared identity. |
| Two symbols have matching descriptions | Treat each Symbol call as a fresh identity. The description is a label, not a link between the created values. |
| Number arithmetic uses decimal-looking fractions | Remember that Number uses binary floating-point. Some decimal fractions lack an exact binary representation, but that does not make every integer or every decimal calculation inaccurate. |
| A BigInt appears | An integer literal such as 17n uses the n suffix and has no fractional part. Before arithmetic, make both operands BigInt or both Number; 17n + 1 mixes the families and throws a TypeError. Keep that arithmetic restriction separate from comparison: mixing the two numeric families does not make every comparison operator throw. |
| Object.is is used | Use its own special-case rules rather than borrowing ===. It treats NaN as the same as itself and distinguishes positive zero from negative zero. |
The tempting wrong routes
- Treating array or function as an extra primitive confuses useful subcategories with the primitive-versus-object split. Check membership in the seven-name list first.
- Reading typeof as a perfect description of the value model fails at null and callable objects. Memorize those specified labels without reclassifying the values.
- Writing a fractional BigInt or moving the n away from the end of an integer mistakes the literal grammar. Put the suffix immediately after an integer value.
- Extending the mixed-numeric arithmetic failure to every comparison uses one operator family's rule for another. Identify whether the expression performs arithmetic or comparison before predicting an error.
- Borrowing the === special cases for Object.is reverses its treatment of NaN and signed zero. Read the named comparison operation before evaluating the pair.
- Comparing contents or descriptions instead of identity makes separate arrays or separate symbols seem equal. Ask whether the same value was reused, not whether the printed forms match.
Try it
Spot the false statement about primitive value immutability.
- A string operation cannot alter the original string value
- A number value cannot be changed internally
- A variable can later hold a different primitive value
- Reassigning a variable mutates its old primitive value
Why can the test 0.1 + 0.2 === 0.3 evaluate to false in JavaScript?
- Some decimal fractions are inexact in binary floating-point
- Strict equality rounds both sides to whole numbers
- Every JavaScript integer is stored approximately
- Addition always converts decimal numbers to strings
Complete the code-reading result: typeof NaN evaluates to which string?
- NaN
- number
- undefined
- object