String.prototype.localeCompare()

Compares two strings in a language-aware order and returns a negative, zero, or positive number.

Signature
localeCompare(compareString)
localeCompare(compareString, locales)
localeCompare(compareString, locales, options)
  • Added in JavaScript ES1 (locales and options added by ECMA-402)

Parameters

ParameterTypeDescription
$compareStringstringThe string to compare the reference string against. Values are coerced to strings, so omitting it compares against the literal text "undefined".
$localesoptionalstring | string[]= the host's default localeA BCP 47 language tag or array of tags, matching the locales parameter of the Intl.Collator constructor. Ignored where Intl.Collator is unavailable.
$optionsoptionalobject= undefinedAn 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, so file2 sorts before file10.
  • 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · javascript
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.

Example · javascript
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

  • Be the first to comment on this lesson.