7 min read

Eye Training · Values, Equality and Numbers

JavaScript converts values quietly. Every bug here is a value that was quietly converted into something else.

Part 2 · Surface 19. Bug counts are hidden and some snippets are clean. See Start Here for how to use these drills.


J · The basics

Bug hunt
J · Retry option
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Order total
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Check the score
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · List the fields
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Missing value
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

M · Three years in, these should jump out

Bug hunt
M · Invoice line
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Age field
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Add tax
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Force update
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Feature flag
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Validate quantity
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Money in paise
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

S · Where seniors stand out

Bug hunt
S · Tweet ids
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
S · Unix timestamp
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
S · Highest bid
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

What your eye checks

Whenever a value is compared, defaulted, converted or used in arithmetic, ask:

  1. Which falsy values are valid here? 0, '' and false are often real values. || and if (!x) throw them away; ?? and == null don't.
  2. What type is it really? Form fields, query strings, environment variables and headers are strings. + concatenates strings.
  3. What does the conversion do with odd input? Number('') is 0, Number('12px') is NaN, parseInt('12px') is 12, global isNaN converts first.
  4. Is it money? Integers in the smallest unit, or a decimal library. Never floats; never toFixed until display.
  5. Is NaN checked with Number.isNaN? And is null excluded before typeof x === 'object'?
  6. Are numbers or versions compared as strings?
  7. Can it exceed the safe range? 64-bit ids beyond 2⁵³ − 1; bitwise operators truncate to 32 bits.
  8. What does the empty case return? Math.max(), Math.min(), averages of nothing (0 / 0 is NaN).

Tells

You seeAsk
x || defaultCan x legitimately be 0, '' or false?
input.value + …String or number?
=== NaNAlways false.
typeof x === 'object'What about null? Arrays?
price * qty with decimalsMoney as floats?
Number(field) then a NaN checkWhat about an empty field?
.toFixed( followed by +It's a string now.
version < '…'Comparing strings?
process.env.X used as a boolean"false" is truthy.
isNaN( without Number.It converts first.
An id field parsed from JSONBigger than 2⁵³?
| 0 or ~~Over 2³¹?
Math.max(...list)Empty list? Huge list?

Go deeper