JavaScript refuse rarement une opération. Additionnez un nombre et une chaîne, comparez un booléen et un tableau : au lieu de s'arrêter, le langage convertit l'un des deux et continue. C'est ce mécanisme qu'on appelle la coercition.
Il explique la plupart des résultats déroutants des premiers mois, et il se maîtrise vite : les règles sont peu nombreuses, juste rarement enseignées d'un bloc.
Définition
La coercition est la conversion automatique d'une valeur vers un autre type, décidée par le langage en fonction de l'opération demandée. Elle est dite implicite quand elle survient seule, explicite quand le développeur la déclenche par un appel.
// Implicite : personne n'a rien demandé
console.log("5" + 3); // "53" le nombre devient une chaîne
console.log("5" - 3); // 2 la chaîne devient un nombre
// Explicite : la conversion est écrite
console.log(Number("5") + 3); // 8
console.log(String(5) + 3); // "53"La différence entre les deux premières lignes tient à un seul détail : l'opérateur + sert à la fois à additionner et à concaténer. Dès qu'une des deux valeurs est une chaîne, il choisit la concaténation. Les opérateurs -, * et / n'ont pas cette ambiguïté.
Les trois destinations possibles
Toute coercition mène vers l'un de trois types, et le contexte suffit à savoir lequel.
| Contexte | Conversion | Exemple |
|---|---|---|
Concaténation avec + | Vers String (chaîne de caractères) | 1 + "a" donne "1a" |
| Calcul, comparaison | Vers Number (nombre) | "10" * 2 donne 20 |
Condition, !, && | Vers Boolean (booléen) | voir Truthy et falsy |
console.log(Number("")); // 0
console.log(Number(null)); // 0
console.log(Number(undefined));// NaN
console.log(Number(true)); // 1
console.log(Number("49 €")); // NaNUne conversion ratée ne lève pas d'erreur : elle produit NaN, qui se propage silencieusement dans tous les calculs suivants. Un total affiché à NaN vient presque toujours d'une saisie non convertie.
S'en protéger sans lutter contre le langage
Trois habitudes suppriment la quasi-totalité des surprises.
- Comparer avec trois signes égal. L'Égalité stricte (===) ne convertit rien, tandis que l'Égalité faible (==) applique des règles qu'aucun développeur ne retient entièrement.
- Convertir les entrées à la frontière. Champ de formulaire, réponse réseau, paramètre d'URL : tout arrive en texte. Convertissez une fois, à l'entrée.
- Vérifier le résultat, pas la source.
Number.isNaN(valeur)après conversion dit immédiatement si la saisie était exploitable.
Questions fréquentes
Pourquoi 1 == "1" est-il vrai ?
Parce que l'égalité faible convertit avant de comparer : la chaîne devient le nombre 1, et les deux se valent. Avec Égalité stricte (===), les types sont comparés d'abord et le résultat est false. C'est la raison pour laquelle la version stricte est recommandée par défaut dans tous les guides de style.
Faut-il utiliser Number() ou parseInt() ?
Number("49 €") donne NaN tandis que parseInt("49 €", 10) donne 49, parce que parseInt lit tant que les caractères sont des chiffres puis s'arrête. Préférez Number() quand la valeur doit être entièrement valide, et parseInt() quand vous acceptez délibérément un préfixe numérique.
La coercition est-elle un défaut du langage ?
C'est un choix de conception assumé, hérité d'une époque où le langage devait rester tolérant dans une page web. Il a un coût réel sur les grands projets, et c'est précisément ce que TypeScript vient corriger en vérifiant les types avant l'exécution.