JS Crime Scene: The Misleading Array

🕵️ JS Crime Scene: The Case of the Misleading Array

📹 Surveillance Footage

The full investigation is available on TikTok:

View the Evidence

The call came in early.

An application was completely misbehaving, data was leaking out of order, and the logs were a mess.

The victim?

Developer Sanity

Someone tried to sort a simple array of integers, and JavaScript decided to play by its own rules.

Let’s inspect the evidence, identify the culprit, and deploy the one-line fix before production collapses entirely.

🔍 The Crime Scene Report

We found a collection of numerical values at the center of the incident.

No complex objects.

No deeply nested structures.

Just raw numbers.

Here is the exact code executed at the scene:

// The Lineup (Original Array)
const numbers = [1, 10, 2, 25, 5];

// The Attempted Sort
numbers.sort();

console.log(numbers);

// Output:
// [1, 10, 2, 25, 5]

📋 The Expected vs. Actual Output

Intended Behavior (Math) Actual Reality (JavaScript) Status
[1, 2, 5, 10, 25] [1, 10, 2, 25, 5] ❌ Maliciously Broken

Look closely at that result.

10 comes before 2?

25 comes before 5?

Did mathematics quietly stop working overnight?

Not exactly.

🕵️‍♂️ The Culprit: UTF-16 String Sorting

When you call .sort() without providing a comparator function, JavaScript does not sort numbers mathematically.

Instead, it secretly performs a type coercion operation and converts every element into a string first.

Our innocent integers suddenly became:

  • 1 → "1"
  • 10 → "10"
  • 2 → "2"
  • 25 → "25"
  • 5 → "5"

Once converted to strings, JavaScript compares them character-by-character using UTF-16 code unit values.

Essentially, the engine starts sorting your numbers like dictionary words.

📖 Think of It Like a Dictionary

In a dictionary:

  • "Apple" comes before "Banana"
  • because "A" comes before "B"

JavaScript applies that exact same logic here.

For example:

  • "10" starts with "1"
  • "2" starts with "2"

Since the character "1" has a lower UTF-16 value than "2", JavaScript places "10" first.

The engine isn’t malfunctioning.

It’s simply following text-based sorting rules.

🛠️ The Fix: Deploying a Comparator Function

To force JavaScript to sort numerically, you must explicitly tell the engine how two values should be compared.

Here’s the proper fix:

const numbers = [1, 10, 2, 25, 5];

// Numeric Sort Fix
numbers.sort((a, b) => a - b);

console.log(numbers);

// Output:
// ✅ [1, 2, 5, 10, 25]

One tiny comparator function.

Massive difference.

⚙️ How the Comparator Actually Works

This line:

(a, b) => a - b

subtracts the second value from the first.

JavaScript then interprets the result.

Negative Result

If the result is negative:

2 - 5 = -3

JavaScript understands that 2 should come before 5.

Positive Result

If the result is positive:

10 - 2 = 8

JavaScript knows 2 should move ahead of 10.

Zero

If the result is 0, both values are considered equal, and their order remains unchanged.

💡 Pro Tip: Reverse Sorting

Need descending order instead?

Just flip the subtraction:

numbers.sort((a, b) => b - a);

Output:

[25, 10, 5, 2, 1]

🚨 Case Closed

Another JavaScript mystery solved.

The golden rule?

Never trust the default behavior of .sort() when working with numbers.

Always provide a comparator function if you want predictable numeric sorting behavior.

Otherwise, JavaScript will happily treat your integers like alphabetized grocery items.

And that’s how 10 ends up beating 2 in a fight it should never win.

Have you ever been burned by JavaScript’s default .sort() behavior in production?

Drop your horror stories below 👇