Strings, numbers and Intl
Everyday methods, floating-point traps and proper formatting.
Updated
What a string is
A string is a sequence of characters — text. It's written between single quotes, double quotes or backticks:
| Syntax | Difference | When |
|---|---|---|
'text' |
— | the default (the convention in most projects) |
"text" |
identical to ' |
when the text contains ' |
`text ${x}` |
template literal: interpolation + multiple lines | when you combine text with variables |
Strings are immutable: no method changes the original string, they all return a new one.
const s = 'hello'
s.toUpperCase() // 'HELLO'
s // 'hello' — unchangedEveryday methods, by category
| You want to... | Method | Example |
|---|---|---|
| clean up spaces | trim(), trimStart(), trimEnd() |
' a '.trim() → 'a' |
| change case | toLowerCase(), toUpperCase() |
case-insensitive comparisons |
| search | includes(), startsWith(), endsWith(), indexOf() |
email.includes('@') |
| extract | slice(start, end), at(-1) |
'hello'.slice(0, 3) → 'hel' |
| split / join | split(sep) / arr.join(sep) |
'a,b'.split(',') → ['a', 'b'] |
| replace | replace(), replaceAll() |
'a-b-c'.replaceAll('-', ' ') |
| pad | padStart(), padEnd() |
'5'.padStart(2, '0') → '05' |
| repeat | repeat(n) |
'ab'.repeat(2) |
slice vs substring: use slice — it also accepts negative indexes (slice(-3) = the last 3 characters).
For complex patterns (validation, extraction) there are regular expressions: /\d+/.test('abc123').
What a number is
JS has a single type for numbers: number — a 64-bit floating point (the IEEE 754 standard). Integers and decimals are the same type.
The famous consequence:
0.1 + 0.2 // 0.30000000000000004It isn't a JS bug — that's how floating point works in almost every language. For money, work in whole cents (1999 instead of 19.99) and format only for display.
Special values
| Value | When it appears | How to check for it |
|---|---|---|
NaN ("not a number") |
a failed conversion: Number('abc') |
Number.isNaN(x) — not x === NaN (it's always false) |
Infinity |
1 / 0 |
Number.isFinite(x) |
Number.MAX_SAFE_INTEGER |
~9 quadrillion | above it → bigint |
Converting string ↔ number
| Method | '42' |
'42px' |
'' |
When |
|---|---|---|---|---|
Number(x) |
42 | NaN |
0 | strict conversion — the default |
parseInt(x, 10) |
42 | 42 | NaN |
reading a number from the start of a text |
parseFloat(x) |
42 | 42 | NaN |
the same, with decimals |
+x |
42 | NaN |
0 | shorthand for Number (less readable) |
String(n), `${n}` |
— | — | — | number → text |
Values from inputs and from FormData are always strings. Convert them explicitly.
Math
Math.round(2.5) // 3
Math.floor(2.9) // 2 (down)
Math.ceil(2.1) // 3 (up)
Math.max(1, 5, 3) // 5
Math.min(...arr) // the minimum of an array
Math.random() // [0, 1)
(3.14159).toFixed(2) // '3.14' — careful, it returns a STRINGIntl — correct formatting, no libraries
Intl is the native API for formatting by language and country. Stop writing thousands separators or month names by hand.
| Formatter | For | Example (en-US) |
|---|---|---|
NumberFormat |
numbers, currency, percentages | $1,234.50, 45% |
DateTimeFormat |
dates and times | October 8, 2026 |
RelativeTimeFormat |
relative time | yesterday, in 3 days |
PluralRules |
picking the plural form | 1 message / 5 messages |
ListFormat |
lists | HTML, CSS, and JS |
const money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })
money.format(1234.5) // '$1,234.50'
new Intl.DateTimeFormat('en-US', { dateStyle: 'long' }).format(new Date())
new Intl.RelativeTimeFormat('en', { numeric: 'auto' }).format(-1, 'day') // 'yesterday'Create the formatter once (outside the function / component) and reuse it — creating it is expensive.
Summary
- Strings are immutable; template literals for interpolation.
- A single
numbertype; money in integers;Number.isNaNfor NaN. - Inputs give you strings — convert them with
Number(). - Formatting:
Intl, not manual concatenation.