learn
JavaScript

Data types and type coercion

typeof quirks, null versus undefined, NaN, equality, and truthy traps.

JavaScript converts types behind your back in exactly the spots where money and access checks live. Interviewers ask this to see whether you can predict an expression's value — and defend user input against silent conversion.

Real-life situation

A cart form sends price and quantity as strings. "4" + 2 totals "42" instead of 6, and the order goes through overcharged. The fix is boring on purpose: convert with Number() at the boundary, reject NaN, and compare with === so types can never sneak past.

Visual

Equality checks
BrowserAPIRealtimeCacheDatabaseShareddurableephemeral

Try it

String money versus real money
javascriptTab moves to the next control
function cartTotal(price, quantity) {
return price + quantity;
}
console.log(cartTotal("4", 2));
console.log(cartTotal(4, 2));
function safeTotal(price, quantity) {
const cleanPrice = Number(price);
const cleanQuantity = Number(quantity);
if (Number.isNaN(cleanPrice)) {
  return "bad price";
}
if (Number.isNaN(cleanQuantity)) {
  return "bad quantity";
}
return cleanPrice + cleanQuantity;
}
console.log(safeTotal("4", 2));
console.log(safeTotal("four", 2));
console.log(safeTotal(4, 0));
Press Run to see the output.
Expected output
42
6
6
bad price
4
Runner helpers

sleep(ms) waits; fakeFetch(url) returns deterministic sample data. Console code runs in a worker with a 5-second limit.

Try changing the last call to safeTotal(4, "") and explain why the result is 4, not "bad quantity". Then try safeTotal(0, 0). Log typeof every value crossing a form boundary for a week; the habit pays for itself.

When to convert, when to compare

Convert at boundaries (forms, URLs, storage) with Number() or String() and nowhere else. Compare with === always; reach for == never. When 0 or "" are valid values, default with ??, not ||.

Loose versus strict — guess first, then reveal.

predict.js
console.log(0 == "");
console.log(0 === "");
console.log(null == undefined);

Interview questions

What is the difference between == and ===?basic

=== compares without conversion: different types are never equal. == converts first, using rules nobody fully remembers — 0 == "" is true, null == undefined is true, [] == false is true. Those surprises are the whole case for ===: it says exactly what it checks. Use === everywhere; the rare deliberate use of == (comparing against null) deserves a comment.

Interviewers also ask

  • Is there any == comparison you would keep?
What does typeof return for the main types, including its famous quirk?basic

typeof returns "undefined", "boolean", "number", "bigint", "string", "symbol" and "function" correctly. The quirk: typeof null is "object" — a bug from the first implementation that can never be fixed without breaking the web. typeof also says "object" for arrays, so pair it with Array.isArray when arrays matter.

Interviewers also ask

  • How do you reliably check for an array?
  • How do you tell null apart from an object?
What is the difference between null and undefined?basic

undefined means no value was ever assigned — a missing argument, a missing property, a function that returns nothing. null means someone deliberately recorded "nothing here", like an empty cart slot waiting for an item. Rule of thumb: JavaScript produces undefined on its own; null in your code should always be a conscious choice.

Interviewers also ask

  • When would you return null from a function?
What is NaN and why does NaN !== NaN?intermediate

NaN is the number value for failed numeric work, like Number("abc"). It is the only value that is not equal to itself, which is why x !== x was once the NaN test. Today use Number.isNaN(x): unlike the global isNaN, it does not coerce first, so Number.isNaN("abc") is correctly false. Any arithmetic touching NaN stays NaN, which is how one bad parse poisons a whole total.

Interviewers also ask

  • What is the difference between isNaN and Number.isNaN?
Which values are falsy?basic

Exactly eight: false, 0, -0, 0n, "", null, undefined and NaN. Everything else is truthy — including "0", "false", empty arrays and empty objects, which trip up beginners daily. That is why if (items) cannot detect an empty array; check items.length instead. When a value like 0 or "" is legitimate input, reach for ?? rather than ||.

Interviewers also ask

  • Is an empty array truthy? Why does that matter?
When does the + operator concatenate and when does it add?intermediate

+ adds only when both sides are already numbers (or bigints); if either side is a string, it converts the other side and concatenates. So 1 + 2 is 3 but "1" + 2 is "12", and "5" - 2 is 3 because - always converts to numbers. A form field total like price + quantity silently becomes "410" instead of 5 — convert inputs with Number() first.

Interviewers also ask

  • How would you debug a total showing 410 instead of 5?
What is the difference between || and ??intermediate

|| falls through on any falsy value, so 0 || 10 is 10 — wrong when zero is a real setting. ?? falls through only on null and undefined, so 0 ?? 10 stays 0. Use ?? for defaults where 0, "" or false are valid, and keep || for cases where any falsy value should trigger the fallback.

Interviewers also ask

  • Can you mix ?? with && or || without parentheses?
What is the difference between primitive and reference values?basic

Primitives (strings, numbers, booleans, null, undefined, symbols, bigints) are copied by value: changing a copy never touches the original. Objects, arrays and functions are references: two variables can point at the same object, and a change through one is visible through the other. That shared visibility is the source of most state bugs — and the reason copying objects needs deliberate tools like spread or structuredClone.

Interviewers also ask

  • How do you copy an object safely?

Key takeaways

  • + concatenates when either side is a string; convert inputs first.
  • === compares type and value; == converts and surprises.
  • Eight falsy values exist; empty arrays and objects are truthy.

References

Last verified: 2026-10-12.

On this page