Comprimento de um objeto em JavaScript: por que não há um .length simples e o que fazer?
\n\nVocê já se pegou pensando: "Por que um array tem a propriedade .length, mas um objeto não?". Se sim, você não está sozinho. A pergunta "Length of a JavaScript object" está entre as mais populares no Stack Overflow, com milhares de visualizações. E não é surpresa: todo iniciante, mais cedo ou mais tarde, tenta escrever obj.length e recebe undefined.
Neste artigo, vamos entender por que isso acontece e, principalmente, como calcular corretamente o comprimento de um objeto em JavaScript. Você aprenderá 4 maneiras práticas, entenderá quando usar cada uma e esquecerá para sempre a confusão com o comprimento de objetos.
\n\nPor que os objetos não têm a propriedade length?
\n\nTudo se resume à natureza dos objetos. Um array é uma coleção ordenada com índices numéricos. O motor do JavaScript pode facilmente dizer: "O array tem 5 elementos". Já um objeto é um conjunto não ordenado de pares chave-valor. Teoricamente, você pode adicionar uma propriedade, removê-la, adicioná-la novamente — e a ordem não é garantida (pelo menos, em especificações antigas).
\n\nÉ por isso que objetos simples não têm um .length embutido. Mas isso não significa que não possamos calculá-lo. Vamos ver como.
Método nº1: Object.keys() — o padrão ouro
\n\nA maneira mais popular e recomendada é usar Object.keys(). Este método retorna um array das propriedades próprias (não herdadas) enumeráveis do objeto. E, como sabemos, um array tem .length.
const user = {\n name: 'Ana',\n age: 28,\n city: 'Moscou',\n isAdmin: false\n};\n\nconst length = Object.keys(user).length;\nconsole.log(length); // 4\n\nSimplesmente genial! Você obtém um array de chaves e então pega seu comprimento. Este método funciona em todos os navegadores modernos e no Node.js.
\n\nO que está incluído em Object.keys()?
\n\nPonto importante: Object.keys() retorna apenas propriedades próprias e enumeráveis. Isso significa que:
- \n
- Próprias — não herdadas via protótipo. Se você criou um objeto através de uma classe ou adicionou um método ao protótipo, ele não aparecerá no resultado. \n
- Enumeráveis — aquelas cuja flag
enumerableestá definida comotrue. Por padrão, todas as propriedades criadas por atribuição são enumeráveis. Mas se você usouObject.defineProperty()comenumerable: false, essa propriedade será ignorada. \n
Exemplo com propriedade não enumerável:
\n\nconst car = {\n brand: 'Toyota',\n model: 'Camry'\n};\n\nObject.defineProperty(car, 'vin', {\n value: 'JT2BF22KX00000001',\n enumerable: false\n});\n\nconsole.log(Object.keys(car).length); // 2 (vin não é contado)\n\nMétodo nº2: Object.values() e Object.entries()
\n\nÀs vezes, você não precisa apenas do número de chaves, mas do número de valores ou pares. Aqui, dois métodos gêmeos ajudam:
\n\n- \n
Object.values(obj)— retorna um array de valores \n Object.entries(obj)— retorna um array de arrays [chave, valor] \n
Ambos retornam arrays e, portanto, têm .length:
const book = {\n title: 'O Mestre e a Margarida',\n author: 'Bulgakov',\n year: 1966\n};\n\nconsole.log(Object.values(book).length); // 3\nconsole.log(Object.entries(book).length); // 3\n\nBasicamente, é a mesma quantidade, mas Object.entries() fornece mais dados se você precisar de chaves e valores posteriormente.
Método nº3: Loop for...in (e como não cair em uma armadilha)
\n\nUma maneira clássica, mas menos conveniente, é usar o loop for...in e contar as propriedades manualmente:
const person = {\n name: 'Ivan',\n age: 30\n};\n\nlet count = 0;\nfor (let key in