String.prototype.repeat()

Small and predictable, with one sharp edge: most string methods clamp or ignore bad arguments, and this one throws.

String methodES2015Live demo
Common call
'-'.repeat(40)
Returns
a new string, count copies long
Replaces
new Array(n + 1).join(s)
Watch out
a negative or infinite count is a RangeError
string.repeat(countcount — How many copies. Truncated toward zero, so 2.9 means 2. Must be zero or more and finite — anything else throws RangeError.type: number · required)
→ string

Demo

Live evaluation
Try:
Inputs
sstringthe string to repeat
countnumberhow many times
Output
'ab'.repeat(3)
'ababab'

Straightforward until the last case. Zero copies give an empty string, which is the sensible answer and the one most code relies on. A negative count, though, is a RangeError rather than an empty string — unusual for a string method, since slice, padStart and the rest all clamp silently. If the count comes from arithmetic that could go negative, guard it with Math.max(0, n) or you will get an exception instead of a harmless empty string.

Parameters

NameTypeRequiredDescription
countnumberyesHow many copies. Truncated toward zero, so 2.9 means 2. Must be zero or more and finite — anything else throws RangeError.

Return value

string — The string concatenated with itself count times. Zero gives an empty string; a negative count throws RangeError.

Common patterns

Draw a divider
The most common use in console output.
console.log('-'.repeat(60));
Indent by depth
Guard the count if depth could be negative.
const indent = '  '.repeat(Math.max(0, depth));
Pad to a width
padStart and padEnd do this without the arithmetic.
const padded = s + ' '.repeat(Math.max(0, width - s.length));

Examples

1. Three copies
'ab'.repeat(3)
Returns
'ababab'
2. Zero copies
'ab'.repeat(0)
Returns
''
3. Truncated
'ab'.repeat(2.9)
Returns
'abab'
4. Negative throws
'ab'.repeat(-1)
Returns
RangeError: Invalid count value: -1
5. Infinity throws
'ab'.repeat(Infinity)
Returns
RangeError: Invalid count value: Infinity
6. Empty source
''.repeat(99)
Returns
''

Pitfalls

1. A negative count throws instead of clamping
Almost every other string method treats an out-of-range number as a no-op. repeat does not. Code computing a count by subtraction — width minus length, depth minus one — will throw on the first input that makes it negative.
Throws
' '.repeat(10 - 'a very long string'.length)
RangeError: Invalid count value: -8
Clamp first
' '.repeat(Math.max(0, 10 - s.length))
''
2. It returns a new string and changes nothing
The usual immutability rule. Worth restating because repeat is often used inside a loop that builds output, where a discarded result is easy to miss.
Discarded
let s = 'ab';
s.repeat(3);
s
'ab'
Assign it
let s = 'ab';
s = s.repeat(3);
s
'ababab'
3. A huge count is a memory problem, not an error
Counts within range but very large allocate exactly what you asked for. A count derived from user input can allocate hundreds of megabytes before the engine finally refuses, which is a denial-of-service vector in server code.
Allocates it all
'x'.repeat(userSuppliedCount)
RangeError only at the engine limit
Bound it
'x'.repeat(Math.min(1000, n))
safe
4. padStart is usually what you meant
Repeating a character to fill a width requires computing the difference, guarding the negative case, and concatenating. The pad methods do all of that, and they never throw.
Manual and fragile
' '.repeat(w - s.length) + s
throws when s is too long
padStart
s.padStart(w)
returns s unchanged

When to use

Use it
  • Dividers and separator lines in console or log output
  • Indentation by nesting depth
  • Building a repeated pattern of known length
Reach for something else
  • Padding to a width → padStart or padEnd, which cannot throw
  • The count may be negative → clamp, or use a pad method
  • The count comes from user input → bound it first
  • Joining a list with a separator → join

Notes

Complexity
O(n × count) in the length of the result
Return
A new string; the original is untouched
CPython impl
V8: Builtins-string-repeat
Memory
Allocates the full result — proportional to count
Thread-safe
Single-threaded; the string is only read

FAQ

Because there is no sensible answer — unlike a slice index, where "past the end" naturally clamps, a negative number of copies is simply meaningless. The specification chose an error over silently treating it as zero, which does catch genuine arithmetic bugs.

'x'.repeat(Math.max(0, n));   // the usual guard

History

ES2015
repeat added, replacing the Array-join idiom.