String.prototype.trim()

The first thing to do with any text a human typed. Its definition of whitespace is broader than the space bar — tabs, newlines, non-breaking spaces and a dozen Unicode separators all count.

String methodES5 (2009)Live demo
Common call
input.value.trim()
Returns
a new string — assign it
Replaces
s.replace(/^\s+|\s+$/g, '')
Watch out
only the ends; interior whitespace is untouched
string.trim()
→ string

Demo

Live evaluation
Try:
Inputs
sstringtext with spaces around it
Output
' hi '.trim()
'hi'

The quotes in the output are what make this readable — they show exactly where the string now begins and ends. Tabs and newlines are whitespace too, so the second case strips them alongside spaces. The third case is the limit of what trim does: the space between 'a' and 'b' survives, because only the ends are touched. The last case collapses to an empty string, which is why `if (input.trim())` is the standard test for whether a user actually typed anything.

Common patterns

Validate a form field
The canonical use — whitespace is not input.
if (!name.trim()) return "Name is required";
Clean parsed fields
Splitting leaves the spaces around delimiters behind.
const fields = line.split(',').map(f => f.trim());
Normalise inner whitespace too
trim does the ends; a replace collapses the middle.
const clean = s.trim().replace(/\s+/g, ' ');

Examples

1. Both ends
' hi '.trim()
Returns
'hi'
2. Tabs and newlines
'\t\n hi '.trim()
Returns
'hi'
3. Leading only
' hi '.trimStart()
Returns
'hi '
4. Trailing only
' hi '.trimEnd()
Returns
' hi'
5. Interior kept
' a b '.trim()
Returns
'a b'
6. All whitespace
' '.trim()
Returns
''

Pitfalls

1. It returns a new string and changes nothing
The single most common trim bug: calling it on a variable and expecting that variable to be clean. Strings are immutable, so the result must be assigned or passed on.
Discarded
let s = ' hi ';
s.trim();
s
' hi '
Assign it
let s = ' hi ';
s = s.trim();
s
'hi'
2. Interior whitespace is not touched
Trimming a name or a search term still leaves double spaces in the middle, so two entries that look identical can compare unequal. Collapse runs of whitespace separately if the comparison matters.
Still differs
'a  b'.trim() === 'a b'
false
Collapse too
'a  b'.trim().replace(/\s+/g, ' ') === 'a b'
true
3. Whitespace includes characters you cannot see
Text pasted from a web page or a word processor often carries a non-breaking space (U+00A0). trim DOES remove it, which is helpful — but a hand-rolled replace of literal spaces will not, and neither will a comparison against " ".
Literal space only
'\u00a0hi'.replace(/ /g, '')
'\u00a0hi'
trim handles it
'\u00a0hi'.trim()
'hi'
4. trimLeft and trimRight are legacy aliases
They are identical to trimStart and trimEnd, kept in Annex B only because old code uses them. The Start/End names match padStart and padEnd, so prefer those.
Legacy name
' hi '.trimLeft()
'hi ' // works, but Annex B
Standard name
' hi '.trimStart()
'hi '

When to use

Use it
  • Any text that came from a human — form fields, pasted content, file input
  • Before comparing or storing a value
  • Cleaning fields after a split
  • Testing whether a field is genuinely empty
Reach for something else
  • You need only one side → trimStart or trimEnd
  • You want to remove something other than whitespace → replace, or slice
  • Interior whitespace matters → collapse it with a replace as well
  • You want to pad rather than strip → padStart, padEnd

Notes

Complexity
O(n) worst case, though typically only the ends are scanned
Return
A new string; the original is untouched
CPython impl
V8: Builtins-string-trim
Memory
Allocates the result, or returns the original when there is nothing to strip
Thread-safe
Single-threaded; the string is only read

FAQ

More than you might expect: space, tab, carriage return, line feed, vertical tab, form feed, the non-breaking space U+00A0, the byte order mark U+FEFF, and the Unicode space separators. It is the same set the language uses for whitespace in source code.

'\u00a0\u2003 hi '.trim();   // 'hi'

History

ES5
trim standardised in 2009, replacing the regex idiom every library had shipped.
ES2019
trimStart and trimEnd standardised, with trimLeft and trimRight kept as Annex B aliases.