Une réponse d'API arrive avec un champ manquant, et le code doit décider quoi faire. Tester la valeur ne suffit pas : un champ absent et un champ contenant zéro ne se distinguent pas si on se contente de regarder ce qu'il vaut.
in répond à la question posée autrement : la propriété est-elle là, quelle que soit sa valeur.
Définition
in est un opérateur qui renvoie true si la propriété nommée à sa gauche existe sur l'objet placé à sa droite. Le nom de la propriété s'écrit entre guillemets, car il s'agit d'un texte.
const client = { nom: 'Marie', credits: 0 };
'nom' in client; // true
'credits' in client; // true
'email' in client; // falseLa deuxième ligne est le cas qui justifie l'opérateur. Écrire if (client.credits) donne faux, parce que zéro est une valeur Truthy et falsy considérée comme fausse, alors que la propriété existe bel et bien.
Ce que in trouve vraiment
L'opérateur ne s'arrête pas aux propriétés propres à l'objet : il remonte aussi la chaîne d'héritage, où se trouvent les méthodes fournies par le langage.
const client = { nom: 'Marie' };
'toString' in client; // true, hérité
Object.hasOwn(client, 'toString'); // false
Object.hasOwn(client, 'nom'); // trueCe comportement est rarement gênant, mais il devient dangereux sur un objet qui sert de dictionnaire alimenté par des données extérieures : 'constructor' in dictionnaire répond true sans que personne n'ait rien ajouté.
| Question posée | Le bon test |
|---|---|
| La propriété existe-t-elle, héritage compris | 'x' in objet |
| L'objet la porte-t-il lui-même | Object.hasOwn(objet, 'x') |
| La valeur est-elle utilisable | objet.x != null |
Sur un tableau, in parle d'indices
Un Array (tableau) étant un objet, l'opérateur y fonctionne, mais il teste la présence d'un indice, jamais celle d'une valeur.
const couleurs = ['rouge', 'vert', 'bleu'];
0 in couleurs; // true
3 in couleurs; // false
'rouge' in couleurs; // false
couleurs.includes('rouge'); // trueAprès un delete sur un élément, l'indice disparaît alors que la longueur du tableau ne bouge pas : 1 in couleurs devient false et le tableau garde un trou. C'est la meilleure démonstration de ce que l'opérateur mesure réellement.
Questions fréquentes
Quelle différence avec objet.x !== undefined ?
La comparaison échoue sur une propriété qui existe mais vaut explicitement undefined : elle répond que la clé est absente alors qu'elle est là. in distingue les deux situations, ce qui compte dès qu'un champ à undefined a un sens métier, par exemple une préférence jamais renseignée.
Peut-on l'utiliser pour chercher une valeur dans un tableau ?
Non, et c'est une confusion fréquente. in regarde les indices, donc 'rouge' in couleurs renvoie faux même si la couleur est dans le tableau. La méthode includes() répond à cette question, et indexOf() donne en plus la position.
C'est le même mot que dans une boucle for...in ?
Le mot est identique, la construction est différente. for (const cle in objet) parcourt les noms de propriétés au lieu de tester une seule d'entre elles, et pour parcourir des valeurs, c'est une boucle of qu'il faut. Deux emplois d'un même mot-clé, à ne pas confondre à la relecture.