Comparing text in JavaScript sounds trivial until you mix types, locales, or Unicode. You might need strict equality between two strings, locale-aware sort order, or a case-insensitive match that still behaves in Turkish, German, or mixed scripts. The wrong tool—usually == or plain toLowerCase()—quietly passes tests in English and fails in production.
Here you will start from === for two strings, see why == is risky when inputs are not guaranteed to be strings, then use localeCompare and Intl.Collator when collation matters. We also cover trim, normalize, and a short character scan example.
Tested on: Node.js v20.18.2. After each snippet, a short note describes the values or lines you should see in the console.
Quick reference
Use this table for javascript compare strings and compare strings js tasks.
| Goal | Approach |
|---|---|
| Same string value, same case | a === b (both strings) |
| Avoid coercion bugs | Prefer ===, not == |
| Sort / locale-aware equality | localeCompare or Intl.Collator with locale + sensitivity |
| Ignore surrounding whitespace | a.trim() === b.trim() (and same normalization strategy) |
| Unicode “looks equal” | normalize("NFC") (or another form), then === |
1. javascript string equals — use ===
For two values that are already strings, === is the usual javascript string compare for equality: same characters, same case, no type conversion.
const str1 = "hello";
const str2 = "hello";
if (str1 === str2) {
console.log("The strings are equal");
} else {
console.log("The strings are not equal");
}You should see The strings are equal.
2. Avoid == for compare strings js (type coercion)
Loose equality == converts operands so "1" and 1 can look “equal,” which is rarely what you want when you care about compare string javascript semantics for text:
const str1 = "1";
const str2 = 1;
if (str1 == str2) {
console.log("The strings are equal");
} else {
console.log("The strings are not equal");
}With ==, you should see The strings are equal even though one operand is a string and one is a number.
The same pair with === shows the safer behavior for mixed types:
const str1 = "1";
const str2 = 1;
if (str1 === str2) {
console.log("The strings are equal");
} else {
console.log("The strings are not equal");
}With ===, you should see The strings are not equal for "1" versus 1.
3. localeCompare — sort order and “equal under locale rules”
localeCompare does not simply compare raw Unicode code units; it follows collation rules for the locale and options you provide (see MDN localeCompare). A return value of 0 means “equivalent” for that configuration; the sign tells you javascript compare string ordering for sorting.
const str1 = "hello";
const str2 = "world";
const result = str1.localeCompare(str2);
if (result === 0) {
console.log("The strings are equal");
} else if (result < 0) {
console.log("The first string comes before the second string");
} else {
console.log("The first string comes after the second string");
}Because "hello" sorts before "world" in default collation, you should see The first string comes before the second string.
Equality under default options (case-sensitive here):
console.log("result:", "hello".localeCompare("hello"));You should see result: 0—two identical strings compare as equivalent under default options.
4. Case-insensitive js compare strings with localeCompare
For javascript string compare when case should be ignored (English example), sensitivity: "base" treats base letters as the same regardless of case:
console.log(
"A vs a (sensitivity base):",
"A".localeCompare("a", "en", { sensitivity: "base" }),
);You should see a line like A vs a (sensitivity base): 0—the trailing 0 means the two strings are equivalent under that locale and options.
Locale matters: with the default locale, Latin I and i often compare as case-insensitive under sensitivity: "accent", but Turkish rules differ:
console.log(
"default accent I vs i:",
"I".localeCompare("i", undefined, { sensitivity: "accent" }) === 0,
);
console.log(
"tr accent I vs i:",
"I".localeCompare("i", "tr", { sensitivity: "accent" }) === 0,
);First line prints default accent I vs i: true under the default locale; the Turkish line prints tr accent I vs i: false, illustrating locale-sensitive casing rules.
That is why MDN recommends localeCompare / Intl.Collator over naive toLowerCase() for i18n (see MDN: comparing strings).
English-only quick check with case folding (fine until you leave simple ASCII):
console.log(
"Hello vs hello (toLowerCase):",
"Hello".toLowerCase() === "hello".toLowerCase(),
);You should see Hello vs hello (toLowerCase): true.
5. Intl.Collator — same ideas as localeCompare
Intl.Collator is the dedicated API for comparisons; localeCompare is specified to align with it in modern engines. Example for compare strings javascript equality ignoring case in English:
const collator = new Intl.Collator("en", { sensitivity: "base" });
console.log("Collator compare A,a:", collator.compare("A", "a"));collator.compare returns 0 for equivalent letters under sensitivity: "base", so the log shows Collator compare A,a: 0.
6. User input: trim and Unicode normalize
Surrounding spaces break naive ===; trim() fixes the common case:
const a = " hi ";
const b = "hi";
console.log(a.trim() === b);After trimming, the comparison is true.
Visually identical text can use different code point sequences. normalize("NFC") is a typical fix before javascript string equals:
const a = "café";
const b = "cafe\u0301";
console.log("raw ===", a === b);
console.log("NFC ===", a.normalize("NFC") === b.normalize("NFC"));You should see raw === false (different code point sequences) and NFC === true once both sides are normalized the same way.
7. Character-by-character check (rare)
You can scan with charAt or indexed access; for plain UTF-16 strings === already compares the full sequence, so this is mostly a teaching pattern unless you add custom early-exit logic:
let str1 = "hello";
let str2 = "Hello";
if (str1.length !== str2.length) {
console.log("The strings are not equal");
} else {
let isEqual = true;
for (let i = 0; i < str1.length; i++) {
if (str1.charAt(i) !== str2.charAt(i)) {
isEqual = false;
break;
}
}
if (isEqual) {
console.log("The strings are equal");
} else {
console.log("The strings are not equal");
}
}Case-sensitive character comparison finds a mismatch on the first letter, so you should see The strings are not equal.
Summary
- Prefer
===for real string equality; avoid==when types can vary. - Use
localeCompare/Intl.Collatorwith explicit locale andsensitivityfor collation and case folding beyond ASCII. - Normalize Unicode and trim whitespace before comparing user-facing text.
References
MDN references for equality, localeCompare, Intl.Collator, and string comparison guidance.
- MDN: Strict equality (
===) - MDN: Equality (
==) - MDN:
String— Comparing strings - MDN:
String.prototype.localeCompare() - MDN:
Intl.Collator - Stack Overflow: Case-insensitive string comparison
