jsguides

Array.prototype.join()

join(separator)

The join() method concatenates all elements of an array into a single string. By default, elements are separated by a comma (,), but you can specify a custom separator as the first argument.

Syntax

join()
join(separator)

Parameters

ParameterTypeDefaultDescription
separatorstring","The string to separate each element. If omitted, elements are separated by a comma.

Examples

The examples below progress from the simplest default call to practical formatting tasks. Each section introduces one behaviour worth knowing before you reach for join() in production code.

Basic usage

const fruits = ["apple", "banana", "cherry"];
console.log(fruits.join());
// "apple,banana,cherry"

console.log(fruits.join(" - "));
// "apple - banana - cherry"

The default comma separator is fine for quick debugging, but the real power of join() comes from the custom separator argument. An empty string works particularly well for building HTML fragments where you want no gaps between elements, and it is often the fastest option.

Building HTML

const items = ["li", "li", "li"];
console.log("<ul>" + items.join("") + "</ul>");
// "<ul><li></li><li></li><li></li></ul>"

HTML construction is a practical use case, but join() works equally well for formatting numeric data. Numbers are automatically converted to strings, so you can produce pipe-delimited or tab-separated output without any mapping step. This automatic coercion saves you an explicit .map(String) call.

Converting numbers to formatted strings

const numbers = [1, 2, 3, 4, 5];
console.log(numbers.join("|"));
// "1|2|3|4|5"

A common edge case to keep in mind: calling join() on an empty array always returns an empty string, regardless of what separator you pass. There is nothing to join, so the result is always zero-length. This is consistent across all engines and never throws.

Empty array

const empty = [];
console.log(empty.join(","));
// ""

Common Patterns

Two real-world patterns stand out: producing comma-separated values for export, and assembling URL query strings from parameter arrays. Both rely on the fact that join() handles any separator string you give it, and both avoid the overhead of manual string concatenation with loops.

CSV generation

const data = ["name", "age", "city"];
console.log(data.join(","));
// "name,age,city"

CSV output is the most direct application, but the same idea extends to URL query strings. The separator changes from a comma to an ampersand, and you prepend a ? to start the query—otherwise the pattern is identical. Both formats rely on the same simple join() call with a different delimiter.

URL query strings

const params = ["page=1", "limit=10", "sort=date"];
console.log("?" + params.join("&"));
// "?page=1&limit=10&sort=date"

Performance Considerations

The join() method creates a new string by iterating through the array once. For small to medium arrays, this is negligible, but for very large arrays with thousands of elements, consider alternatives like streaming or incremental building.

A quick benchmark shows the difference between join() and building strings manually:

const arr = Array.from({ length: 10000 }, (_, i) => String(i));

// join() — single pass, engine-optimised
console.time('join');
arr.join(',');
console.timeEnd('join');

Comparing with reduce

While you can use reduce() to achieve similar results, join() is optimized specifically for string concatenation and is typically faster when you already have an array of values to combine. reduce() gives you more control, but it also adds more callback overhead and more room for accidental formatting bugs.

Handling different types

join() automatically converts all elements to strings using their toString() method:

const mixed = [1, true, 'hello', null, undefined, { id: 1 }];
console.log(mixed.join(' | '));
// "1 | true | hello |  |  | [object Object]"

Note how null and undefined become empty strings in the output. That behavior can be helpful when you want to tolerate missing values, but it can also hide data quality problems if you expected every slot to contain a real value.

Working with nested arrays

join() does not recursively flatten — nested arrays produce their default toString() output. For deeply nested arrays, flatten first using flat():

const nested = [1, [2, 3], [4, [5, 6]]];
console.log(nested.join(','));
// "1,2,3,4,5,6"

const deep = [1, [2, 3], [4, [5, 6]]];
console.log(deep.flat(2).join(','));
// "1,2,3,4,5,6"

Choosing the right separator

The separator is part of the meaning of the output, not just decoration. A comma is fine for display, but it can be awkward if the values themselves may contain commas. In those cases, use a safer delimiter or escape the values first. The same idea applies to pipes, tabs, and newline-separated data.

For machine-readable formats, join() is a building block rather than a full serializer. It works well for simple query strings, HTML fragments, and ad hoc exports, but structured formats usually need more careful escaping. If your data can contain quotes, separators, or control characters, format each element before joining them.

Edge Cases

  • Empty array: Returns an empty string
  • Single element: Returns that element as a string (no separator)
  • Undefined elements: Converted to empty strings
  • Objects: Use map() to convert objects to meaningful strings before calling join()

See Also