Coercion in JavaScript: when the language converts types on its own

Coercion is the automatic conversion of a value from one type to another, performed by JavaScript before comparing or calculating.
3 min read
Believemy logo

JavaScript rarely refuses an operation. Add a number to a string, compare a boolean with an array: instead of stopping, the language converts one of the two and carries on. That mechanism is called coercion.

It explains most of the puzzling results people hit in their first months, and it is quickly mastered: the rules are few, they are just rarely taught in one place.


Definition

Coercion is the automatic conversion of a value to another type, decided by the language based on the operation requested. It is implicit when it happens on its own, and explicit when the developer triggers it with a call.

JAVASCRIPT
// Implicit: nobody asked for this
console.log("5" + 3);  // "53"  the number becomes a string
console.log("5" - 3);  // 2     the string becomes a number

// Explicit: the conversion is written down
console.log(Number("5") + 3);  // 8
console.log(String(5) + 3);    // "53"

The difference between the first two lines comes down to one detail: the + operator both adds and concatenates. As soon as one of the two values is a string, it picks concatenation. The -, * and / operators carry no such ambiguity and always convert toward numbers.


The three possible destinations

Every coercion leads to one of three types, and the context is enough to know which.

ContextConversionExample
Concatenation with +To String1 + "a" gives "1a"
Arithmetic, comparisonTo Number"10" * 2 gives 20
Condition, !, &&To Booleansee Truthy and falsy
JAVASCRIPT
console.log(Number(""));       // 0
console.log(Number(null));     // 0
console.log(Number(undefined));// NaN
console.log(Number(true));     // 1
console.log(Number("49 usd")); // NaN
Good to know

A failed conversion raises no error: it produces NaN, which then spreads silently through every following calculation. A total displayed as NaN almost always comes from an unconverted input.


Protecting yourself without fighting the language

Three habits remove nearly every surprise.

  • Compare with three equals signs. Strict equality (===) converts nothing, whereas Loose equality (==) applies rules no developer remembers in full.
  • Convert inputs at the boundary. A form field, a network response, a URL parameter: everything arrives as text. Convert once, on the way in, rather than ten times further down.
  • Check the result, not the source. Number.isNaN(value) right after conversion tells you immediately whether the input was usable.


Frequently asked questions

Question

Why is 1 == "1" true?

Because loose equality converts before comparing: the string becomes the number 1, and the two match. With Strict equality (===), types are compared first and the result is false. That is why the strict version is the default recommendation in every style guide.


Question

Should I use Number() or parseInt()?

Number("49 usd") gives NaN while parseInt("49 usd", 10) gives 49, because parseInt reads while the characters are digits then stops. Prefer Number() when the value must be entirely valid, and parseInt() when you deliberately accept a numeric prefix.


Question

Is coercion a flaw in the language?

It is a deliberate design choice, inherited from a time when the language had to stay forgiving inside a web page. It carries a real cost on large projects, and that is exactly what TypeScript corrects by checking types before execution. The language itself never changed on this point, so as not to break the existing web.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.