JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
206: Locale-Aware Sorting and Comparison
For a long time, I just assumed Array.prototype.sort() worked the way I expected it to. You give it a list of strings, it puts them in alphabetical order, and you move on with your day. But if you've ever built an app for a global audience, you've likely run into the moment where you realize that "alphabetical order" is a much more complicated concept than the computer understands by default.
The ASCII Trap
The problem is that by default, JavaScript sorts strings by comparing their UTF-16 code unit values. To the engine, it's not comparing letters; it's comparing numbers. This works fine for a list of all-lowercase English words, but it falls apart the second you introduce mixed casing or accented characters. Take a look at this:
const names = ['Zoe', 'apple', 'Áaron', 'Bob'];
names.sort();
console.log(names); // ['Bob', 'Zoe', 'apple', 'Áaron']
If you're looking at that result, you're probably thinking, "Wait, why is apple after Zoe?" and "Why is Áaron at the very end?" It's because uppercase letters have lower code values than lowercase letters, and accented characters are tucked away far further down the character map. In a real-world user interface, this looks like a bug. No user expects their contact list to be sorted by the internal numeric value of a character encoding.
The Quick Fix: localeCompare
The easiest way to fix this is by providing a comparator function to sort() using the localeCompare() method. This method is built specifically to handle the linguistic rules of a given language. Instead of comparing raw numbers, it asks the environment how these strings should actually be ordered.
const names = ['Zoe', 'apple', 'Áaron', 'Bob'];
names.sort((a, b) => a.localeCompare(b));
console.log(names); // ['apple', 'Áaron', 'Bob', 'Zoe']
Suddenly, the list makes sense. localeCompare handles the casing and the accent on "Áaron" correctly. If you're dealing with a small array, this is usually all you need. It's concise and it gets the job done without much fuss.
Scaling with Intl.Collator
However, if you're sorting a list of five thousand rows in a data table, calling localeCompare inside the sort loop is a performance killer. Every single time the sort algorithm compares two elements, it has to initialize the locale settings for that comparison. It's a lot of overhead for a repetitive task.
This is where Intl.Collator comes in. Think of it as a "pre-configured" version of localeCompare. You create the collator instance once, and then you use its compare method. I always reach for this when performance matters or when I need fine-grained control over the sorting logic.
const names = ['Zoe', 'apple', 'Áaron', 'Bob'];
const collator = new Intl.Collator('en', { sensitivity: 'base', numeric: true });
names.sort(collator.compare);
console.log(names);
The real power here is in the options object. By setting sensitivity: 'base', I can tell JavaScript to ignore accents and case entirely (treating 'a' and 'Á' as the same letter). And numeric: true is a lifesaver—it ensures that "Item 2" comes before "Item 10". Without it, you get the classic "1, 10, 2" sorting nightmare because "10" starts with "1", which comes before "2".
Between the two, localeCompare is great for the "one-off" sort, but Intl.Collator is the professional tool for production-grade lists. It's cleaner, faster, and gives you the control you need to make sure your UI doesn't frustrate users from different parts of the world.
📋 Practical Task
International City Directory Sort
You are building a city directory for a travel app. The current implementation uses a naive .sort(), which is causing cities like "Örebro" and "Zürich" to appear at the end of the list, and "City 10" to appear before "City 2".
Your Task: Rewrite the sorting logic using Intl.Collator to ensure the list is sorted linguistically and numerically.
const cities = [
"Zürich",
"appleton",
"Örebro",
"City 2",
"City 10",
"Berlin",
"city 1"
];
// FIX THIS LINE:
cities.sort();
console.log(cities);
// Expected output: ["appleton", "Berlin", "city 1", "City 2", "City 10", "Örebro", "Zürich"]
// (Note: exact order of a/B/c may vary by locale, but numeric and accented logic must be correct)
There are no comments for now.