String.prototype.localeCompare()
Compares two strings in a language-aware order and returns a negative, zero, or positive number.
localeCompare(compareString)
localeCompare(compareString, locales)
localeCompare(compareString, locales, options)- Added in JavaScript ES1 (locales and options added by ECMA-402)
Parameters
| Parameter | Type | Description |
|---|---|---|
$compareString | string | The string to compare the reference string against. Values are coerced to strings, so omitting it compares against the literal text "undefined". |
$localesoptional | string | string[]= the host's default locale | A BCP 47 language tag or array of tags, matching the locales parameter of the Intl.Collator constructor. Ignored where Intl.Collator is unavailable. |
$optionsoptional | object= undefined | An options object matching the Intl.Collator options parameter, supporting sensitivity, numeric, ignorePunctuation, caseFirst and usage. Ignored where Intl.Collator is unavailable. |
Return value
numberA negative number if the reference string sorts before compareString, a positive number if it sorts after, and 0 if they are considered equivalent. The exact magnitude is implementation-defined.
Errors
Throws a RangeError if locales contains an invalid language tag or options contains an invalid property value.
Changelog
- PHP ECMA-402The locales and options arguments were added by the Internationalization API; implementations without Intl.Collator ignore them entirely.
Sorting strings with < compares UTF-16 code units, which puts every capital letter before every lowercase one and files accented letters after z. localeCompare() instead applies real collation rules for a language, and it is the comparator you should hand to Array.prototype.sort() for anything a person reads.
The options that matter
sensitivity: "base"— ignore both case and accents;"accent"ignores case only.numeric: true— compare embedded digit runs as numbers, sofile2sorts beforefile10.ignorePunctuation: true— skip punctuation when ordering.
What trips people up
Never test for === -1 or === 1. The spec only promises the sign, and engines return values like -2. Compare against zero, or wrap in Math.sign().
Results also vary by locale: ä sorts next to a in German but after z in Swedish. If the output feeds a test, a snapshot, or a stored order, pass an explicit locale rather than relying on the host default.
For sorting large arrays, build one Intl.Collator and reuse its compare method — it avoids rebuilding the collator on every comparison.
Example
When to use it
- Sort a list of customer names correctly for a German or Swedish audience
- Order filenames so file2 comes before file10
- Match a search term against a name while ignoring case and accents
- Sort a dropdown's options in the user's own language
Frequently asked questions
How do I sort an array of strings alphabetically in JavaScript?
Pass localeCompare as the comparator: arr.sort((a, b) => a.localeCompare(b, "en")). The bare arr.sort() compares UTF-16 code units, which places all capitals before lowercase letters and mis-files accented characters.
Why does localeCompare return 2 instead of 1?
The specification only guarantees the sign of the return value, not its magnitude, so engines are free to return -2, 2, or any other value. Always test result < 0, result > 0, or result === 0.
How do I compare strings ignoring accents and case?
Pass sensitivity: "base" — a.localeCompare(b, "en", { sensitivity: "base" }) === 0 treats "resume", "Resume" and "résumé" as equivalent. Use "accent" instead when case should be ignored but accents should still count.
More examples
Natural ordering of numbered strings
The default sort and a plain locale compare both order lexicographically, putting file10 before file2 because "1" precedes "2". Passing numeric: true makes the collator read digit runs as numbers, producing the order a human expects.
const files = ["file10.txt", "file2.txt", "file1.txt"];
console.log([...files].sort());
console.log([...files].sort((a, b) => a.localeCompare(b, "en")));
console.log(
[...files].sort((a, b) => a.localeCompare(b, "en", { numeric: true })),
);Reusing one collator for a large sort
Creating the Intl.Collator once and passing its compare method avoids rebuilding collation data on every pair, which matters for long lists. With sensitivity "base" the two spellings of éclair compare as equivalent, so the call returns 0.
const collator = new Intl.Collator("en", {
sensitivity: "base",
numeric: true,
});
const rows = ["Item 10", "éclair", "Eclair", "item 2"];
console.log(rows.sort(collator.compare));
console.log(collator.compare("éclair", "Eclair"));
Discussion