Code JavaScript sur fond sombre illustrant la vérification d'un objet vide

Comment détecter un objet vide en JavaScript ?

Publié le

Un objet vide en JavaScript, ça paraît simple : {}, pas de propriétés, rien dedans. Mais le détecter proprement est une source régulière d'erreurs. Est-ce que l'objet existe vraiment ? Est-ce qu'il n'est pas null ou undefined ? Et si certaines propriétés sont présentes mais valent undefined ? Voici les différentes méthodes pour vérifier qu'un objet est vide, leurs limites, et comment choisir la bonne selon votre contexte.

D'abord : vérifier que l'objet existe bien

Avant de tester si un objet est vide, il faut s'assurer qu'il existe. En JavaScript, accéder aux propriétés d'une valeur null ou undefined lève immédiatement une erreur. C'est le premier risque à écarter.

const utilisateur = null;

// ❌ Ça plante : TypeError: Cannot convert undefined or null to object
Object.keys(utilisateur);

Avant tout test "est-il vide ?", ajoutez donc une garde sur l'existence de l'objet :

function estObjetVide(obj) {
  if (obj === null || obj === undefined) {
    return true; // ou false selon votre logique métier
  }
  return Object.keys(obj).length === 0;
}
⚠ null n'est pas un objet vide. typeof null retourne "object" en JavaScript, c'est un bug historique du langage qui ne sera jamais corrigé. Ne vous fiez pas à typeof pour distinguer un vrai objet de null. Utilisez toujours un test strict === null.

La méthode recommandée : Object.keys()

C'est aujourd'hui la solution la plus lisible, la plus directe et la mieux supportée pour détecter un objet vide. Object.keys() retourne un tableau contenant les noms de toutes les propriétés propres et énumérables de l'objet. Si ce tableau est vide, l'objet l'est aussi.

const objVide = {};
const objPlein = { nom: 'Alice', age: 30 };

Object.keys(objVide).length === 0; // true → objet vide
Object.keys(objPlein).length === 0; // false → objet non vide

Simple, expressif, et performant pour la grande majorité des cas. C'est la méthode à retenir en premier choix.

Les variantes : Object.values() et Object.entries()

Le même raisonnement s'applique avec Object.values() (tableau des valeurs) et Object.entries() (tableau des paires clé/valeur). Les trois méthodes renvoient un tableau vide sur un objet vide, donc le test .length === 0 fonctionne de la même façon.

const obj = {};

Object.keys(obj).length === 0; // true
Object.values(obj).length === 0; // true
Object.entries(obj).length === 0; // true

En pratique, Object.keys() est préféré parce qu'il est légèrement plus performant, il ne lit que les noms de propriétés, sans accéder à leurs valeurs.

L'approche avec for...in

Avant ES6 et l'arrivée de Object.keys(), la façon classique de tester un objet vide était de tenter d'itérer dessus avec une boucle for...in. Si la boucle ne s'exécute pas une seule fois, l'objet est vide.

function estVide(obj) {
  for (const cle in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, cle)) {
      return false; // au moins une propriété propre → pas vide
    }
  }
  return true;
}

Notez la vérification avec hasOwnProperty : for...in remonte aussi dans la chaîne de prototypes et peut énumérer des propriétés héritées. Sans ce filtre, un objet qui n'a aucune propriété propre mais qui hérite de propriétés énumérables serait considéré à tort comme non vide.

⚠ Privilégiez Object.keys() à for...in. La boucle for...in sans filtre hasOwnProperty est une source classique de bugs. Object.keys() ne retourne que les propriétés propres et énumérables, ce qui est généralement ce qu'on veut. Réservez for...in aux cas où vous avez besoin d'itérer sur les propriétés héritées.

L'approche avec JSON.stringify()

Une autre méthode qu'on voit régulièrement consiste à sérialiser l'objet en JSON et à comparer le résultat à la chaîne "{}".

JSON.stringify({}) === '{}'; // true
JSON.stringify({ a: 1 }) === '{}'; // false

Ça fonctionne dans les cas simples, mais cette approche a des limites importantes qu'il faut connaître.

Les pièges de JSON.stringify()

JSON.stringify() ignore silencieusement certaines valeurs : les propriétés dont la valeur est undefined, les fonctions, et les symboles. Un objet qui contient ces types de valeurs sera sérialisé en "{}" alors qu'il n'est pas techniquement vide.

const obj = {
  action: function() {},
  valeur: undefined,
  cle: Symbol('id')
};

JSON.stringify(obj) === '{}'; // true, mais l'objet a 3 propriétés !
Object.keys(obj).length === 0; // false, réponse correcte

De plus, sérialiser un objet volumineux juste pour tester s'il est vide est inutilement coûteux. Object.keys() est bien plus efficace.

Les propriétés héritées et les prototypes

Object.keys() ne retourne que les propriétés propres et énumérables de l'objet, pas celles héritées via le prototype. Dans la quasi-totalité des cas, c'est le comportement voulu. Mais si vous travaillez avec des objets créés via une classe ou Object.create(), sachez que les méthodes héritées ne sont pas comptabilisées.

class Utilisateur {
  saluer() { return 'Bonjour'; }
}

const u = new Utilisateur();

Object.keys(u).length === 0; // true → pas de propriétés propres
// mais u.saluer() existe bien, via le prototype

Un objet instance sans propriétés propres sera donc détecté comme vide par Object.keys(). C'est souvent correct (on teste les données, pas les méthodes), mais il faut en être conscient.

Les propriétés non énumérables

En JavaScript, les propriétés peuvent être marquées comme non énumérables via Object.defineProperty(). Ces propriétés sont invisibles pour Object.keys(), for...in et JSON.stringify(). Si vous avez besoin d'inclure les propriétés non énumérables dans votre test, utilisez Object.getOwnPropertyNames().

const obj = {};
Object.defineProperty(obj, 'secret', {
  value: 42,
  enumerable: false
});

Object.keys(obj).length === 0; // true, n'en tient pas compte
Object.getOwnPropertyNames(obj).length === 0; // false, la voit

Ce cas est rare dans du code applicatif courant, mais c'est une distinction utile à connaître si vous travaillez avec des bibliothèques tierces ou des objets créés de façon non conventionnelle.

Créer une fonction utilitaire réutilisable

Plutôt que de répéter ce test partout dans votre code, le bon réflexe est d'encapsuler la logique dans une fonction qui gère tous les cas : null, undefined, valeur non-objet, et objet réellement vide.

/** * Retourne true si la valeur est un objet vide {}, * false dans tous les autres cas (null, undefined, * tableau, objet avec propriétés…) */
function estObjetVide(valeur) {
  if (valeur === null || valeur === undefined) {
    return false;
  }
  if (typeof valeur !== 'object' || Array.isArray(valeur)) {
    return false;
  }
  return Object.keys(valeur).length === 0;
}

estObjetVide({}); // true
estObjetVide({ a: 1 }); // false
estObjetVide(null); // false
estObjetVide([]); // false
estObjetVide('texte'); // false

Notez le test sur Array.isArray() : un tableau vide [] est de type "object", mais ce n'est pas un objet vide au sens où on l'entend généralement. Ce filtre évite les faux positifs.

✓ Bonne pratique. Placez cette fonction dans un fichier utilitaire partagé (utils.js ou helpers.js) et importez-la là où vous en avez besoin. Évitez de réimplémenter ce test en ligne à chaque fois : la cohérence du comportement dans toute l'application dépend d'une seule source de vérité.

Lever une alerte ou une erreur quand un objet est vide

Détecter un objet vide n'a de valeur que si l'on fait quelque chose avec cette information. Selon le contexte, réponse d'une API, paramètre d'une fonction, configuration chargée depuis le localStorage, la réaction attendue varie.

Dans une réponse d'API

Quand vous attendez des données depuis un serveur, une réponse {} n'est souvent pas une erreur technique mais un cas métier à traiter : ressource introuvable, accès refusé, résultat vide.

async function chargerProfil(id) {
  const reponse = await fetch(`/api/utilisateurs/${id}`);
  const donnees = await reponse.json();

  if (estObjetVide(donnees)) {
    console.warn(`Profil introuvable pour l'id ${id}`);
    return null;
  }

  return donnees;
}

Dans une fonction utilitaire ou une bibliothèque interne

Si une fonction attend impérativement un objet non vide pour fonctionner, il vaut mieux lever une erreur explicite plutôt que de laisser planter silencieusement plus loin dans le code.

function construireUrl(params) {
  if (estObjetVide(params)) {
    throw new Error('construireUrl attend un objet de paramètres non vide.');
  }
  return '?' + new URLSearchParams(params).toString();
}

construireUrl({}); // ❌ Error: construireUrl attend...
construireUrl({ page: 2 }); // ✓ "?page=2"
✓ Erreur explicite plutôt que comportement silencieux. Un throw new Error() avec un message clair est infiniment plus facile à déboguer qu'une valeur undefined qui remonte cinq niveaux plus haut dans la pile d'appels. Validez les entrées en début de fonction.

Dans l'interface utilisateur

Côté UI, un objet vide signifie souvent qu'il n'y a rien à afficher. Plutôt que de laisser un composant rendu vide ou cassé, on affiche un état explicite.

function afficherResultat(resultat) {
  const zone = document.getElementById('zone-resultat');

  if (estObjetVide(resultat)) {
    zone.textContent = 'Aucun résultat trouvé.';
    return;
  }

  // On peut travailler avec resultat en toute sécurité
  zone.innerHTML = `<p>${resultat.titre}</p>`;
}

Propriétés présentes mais valant undefined ou null

Une situation souvent source de confusion : un objet qui a des propriétés, mais dont les valeurs sont undefined ou null. Cet objet n'est pas vide au sens strict, ses clés existent.

const obj = { nom: undefined, age: null };

Object.keys(obj).length === 0; // false → 2 clés présentes

Si votre besoin est de détecter un objet "sans données utiles" (toutes les valeurs sont vides ou absentes), il faut compléter le test :

function sansValeurUtile(obj) {
  if (!obj || typeof obj !== 'object') return true;
  return Object.values(obj).every(
    v => v === null || v === undefined || v === ''
  );
}

sansValeurUtile({ nom: null, age: undefined }); // true
sansValeurUtile({ nom: 'Alice', age: null }); // false

Cette logique est plus proche d'une validation métier que d'un simple test d'objet vide. Adaptez les conditions dans le .every() selon ce que vous considérez comme "sans valeur utile" dans votre contexte.

Synthèse

Situation Ce qu'on utilise
Tester un objet vide dans le cas général Object.keys(obj).length === 0
Avant tout test, vérifier que l'objet existe Vérification explicite === null / === undefined
Éviter les faux positifs avec les tableaux Object.keys() + Array.isArray()
Inclure les propriétés non énumérables Object.getOwnPropertyNames(obj).length === 0
Tester si toutes les valeurs sont vides (null, undefined…) Object.values(obj).every(...)
Lever une erreur si l'objet est vide Garde en début de fonction + throw new Error()

Pour la très grande majorité des cas, Object.keys(obj).length === 0 précédé d'une vérification de l'existence de l'objet est tout ce dont vous avez besoin. Les variantes avec getOwnPropertyNames() ou Object.values().every() sont à réserver aux besoins spécifiques où la sémantique de "vide" est différente.

Vous travaillez sur de la validation de données en JavaScript ?

Gestion des cas limites, structures imbriquées, validation avant envoi à une API : si vous avez un cas concret à résoudre, on peut en parler.

Poser une question
Code JavaScript avec une case à cocher illustrant la détection d'état Comment vérifier si une checkbox est cochée ?

Propriété checked, événement change, lien avec un bouton, récupération au submit avec FormData : tout ce qu'il faut savoir sur les checkboxes en JavaScript.

Écran d'ordinateur affichant du code HTML et JavaScript Comment faire un quiz en HTML et JavaScript ?

Apprenez à créer un quiz interactif en HTML, CSS et JavaScript. Structure HTML, style CSS et logique JavaScript expliqués étape par étape.

Développeur devant son ordinateur Comment filtrer et supprimer des éléments d'un tableau en JavaScript ?

Découvrez les différentes méthodes pour supprimer des éléments d'un tableau en JavaScript : filter(), splice() et l'utilisation d'une liste d'exclusions.