AI in Recruitment Practical Strategies for Better Hiring

6 min de leitura

Entendendo o Object e o conceito de “objeto de objeto” em JavaScript

Os conceitos de objetos em JavaScript costumam gerar dúvidas, especialmente quando começamos a trabalhar com estruturas mais complexas, como “objetos de objetos” (objetos aninhados). Este artigo vai esclarecer:

– O que é o tipo primitivo `object` em JavaScript
– A diferença entre classe, instância e objeto
– O que é, na prática, um “objeto de objeto”
– Como acessar e manipular propriedades em objetos aninhados
– Boas práticas para trabalhar com esse tipo de estrutura

## 1. O que é um `object` em JavaScript?

Em JavaScript, quase tudo que não é um tipo primitivo básico (`string`, `number`, `boolean`, `null`, `undefined`, `symbol`, `bigint`) é um **objeto**.

De forma simplificada:

– Um **objeto** é uma coleção de pares **chave → valor**
– Essas chaves (propriedades) podem armazenar qualquer tipo de dado:
– valores primitivos
– funções
– outros objetos

Exemplo básico de objeto:

js
const usuario = {
nome: “Ana”,
idade: 28,
ativo: true
};

Aqui, `usuario` é um objeto do tipo `object` e possui três propriedades: `nome`, `idade` e `ativo`.

## 2. Classe vs instância vs objeto

Antes de entrar em “objeto de objeto”, vale alinhar conceitos que costumam se misturar:

– **Classe**: é um “molde” (ou modelo) que define a estrutura e comportamento de algo.
– **Instância**: é um “exemplar” concreto criado a partir dessa classe.
– **Objeto**: em JavaScript, a instância de uma classe é um objeto; mas também podemos criar objetos sem classe (via literal de objeto).

Exemplo com classe:

js
class Usuario {
constructor(nome, idade) {
this.nome = nome;
this.idade = idade;
}

saudacao() {
console.log(`Olá, meu nome é ${this.nome}`);
}
}

const ana = new Usuario(“Ana”, 28); // ana é uma instância de Usuario
// ana é um objeto

Exemplo sem classe (objeto literal):

js
const usuario = {
nome: “Ana”,
idade: 28,
saudacao() {
console.log(`Olá, meu nome é ${this.nome}`);
}
};

Nos dois casos estamos lidando, no fim, com um **objeto**. A grande diferença é a forma como esse objeto é criado.

## 3. O que é um “objeto de objeto” (objeto aninhado)?

“Objeto de objeto” nada mais é do que um **objeto que possui, em alguma de suas propriedades, outro objeto**.

Em outras palavras, é um **objeto aninhado** (nested object).

Exemplo:

js
const empresa = {
nome: “B2Bit”,
endereco: {
rua: “Av. Exemplo”,
numero: 123,
cidade: “São Paulo”,
estado: “SP”
}
};

– `empresa` é um objeto
– `endereco` também é um objeto
– `endereco` é uma propriedade de `empresa`

Portanto, `empresa` é um **objeto de objeto**: ele contém outro objeto dentro dele.

Este tipo de estrutura é extremamente comum quando lidamos com:

– Respostas de APIs (JSON)
– Modelagem de domínios mais complexos (usuários, pedidos, produtos, configurações, etc.)

## 4. Visualizando um objeto de objeto

Diagrama representando um objeto em JavaScript contendo outro objeto em uma de suas propriedades
Um objeto pode conter outro objeto em uma de suas propriedades, formando uma estrutura aninhada

Podemos pensar assim:

– Cada “caixa” é um objeto
– Dentro da caixa “pai” existe outra caixa, que também é um objeto
– O acesso é feito navegando por essas “caixas” através de suas chaves

## 5. Acessando propriedades em objetos aninhados

Com objetos simples:

js
const usuario = {
nome: “Ana”,
idade: 28
};

console.log(usuario.nome); // “Ana”

Com objetos de objetos:

js
const usuario = {
nome: “Ana”,
endereco: {
cidade: “São Paulo”,
estado: “SP”
}
};

console.log(usuario.endereco.cidade); // “São Paulo”

Também podemos acessar usando colchetes:

js
console.log(usuario[“endereco”][“cidade”]); // “São Paulo”

Essa sintaxe com colchetes é útil quando a chave está em uma variável:

js
const prop = “cidade”;
console.log(usuario.endereco[prop]); // “São Paulo”

## 6. Atualizando e criando propriedades em objetos aninhados

Para **atualizar**:

js
usuario.endereco.cidade = “Campinas”;

Para **criar** uma nova propriedade em um objeto interno:

js
usuario.endereco.cep = “00000-000”;

Se o objeto interno ainda não existir, primeiro você precisa criá-lo, senão receberá erro de acesso a `undefined`:

js
const usuario = {
nome: “Ana”
};

// usuario.endereco.cidade // ERRO: endereco é undefined

usuario.endereco = {}; // cria o objeto interno
usuario.endereco.cidade = “São Paulo”;

## 7. Profundidade de objetos: vários níveis de aninhamento

É possível ter mais de um nível de aninhamento:

js
const sistema = {
usuario: {
dadosPessoais: {
nome: “Ana”,
idade: 28
},
configuracoes: {
tema: “dark”,
notificacoes: true
}
}
};

Para acessar:

js
console.log(sistema.usuario.dadosPessoais.nome); // “Ana”
console.log(sistema.usuario.configuracoes.tema); // “dark”

Essa estrutura continua sendo apenas um grande objeto que contém outros objetos em várias camadas.

## 8. Lidando com erros ao acessar objetos aninhados

Um problema frequente é tentar acessar uma propriedade de algo que é `undefined`:

js
const usuario = {};

console.log(usuario.endereco.cidade);
// TypeError: Cannot read properties of undefined (reading ‘cidade’)

Porque `usuario.endereco` é `undefined`.

### 8.1. Operador de encadeamento opcional (`?.`)

O operador `?.` ajuda a evitar esse erro:

js
console.log(usuario.endereco?.cidade); // undefined (não quebra)

Se `endereco` for `undefined` ou `null`, a expressão é interrompida e retorna `undefined`.

Outro exemplo com vários níveis:

js
console.log(sistema.usuario?.dadosPessoais?.nome);

Se qualquer etapa no caminho for `undefined` ou `null`, o resultado será `undefined`, não um erro.

## 9. Copiando e clonando objetos de objetos

Outro ponto que costuma confundir é copiar objetos, especialmente quando há objetos internos.

### 9.1. Cópia por referência

Em JavaScript, objetos são copiados **por referência**, não por valor:

js
const endereco = {
cidade: “São Paulo”,
estado: “SP”
};

const endereco2 = endereco;

endereco2.cidade = “Campinas”;

console.log(endereco.cidade); // “Campinas”

`endereco` e `endereco2` apontam para o mesmo objeto na memória.

### 9.2. Cópia rasa (shallow copy)

Usando o operador spread (`…`), você faz uma cópia **apenas do primeiro nível**:

js
const usuario = {
nome: “Ana”,
endereco: {
cidade: “São Paulo”,
estado: “SP”
}
};

const copia = { …usuario };

copia.nome = “João”; // muda só em ‘copia’
copia.endereco.cidade = “Campinas”; // afeta usuario.endereco também

console.log(usuario.endereco.cidade); // “Campinas”

A propriedade `endereco` continua sendo o mesmo objeto em ambos.

### 9.3. Cópia profunda (deep copy)

Para copiar também os objetos internos, precisamos de uma **cópia profunda**. Uma forma simples (embora com limitações) é:

js
const copiaProfunda = JSON.parse(JSON.stringify(usuario));

Isso cria novos objetos em todos os níveis, mas não lida bem com funções, `Date`, `Map`, `Set` etc. Para casos mais complexos, usam-se bibliotecas específicas ou implementações próprias.

## 10. Objetos de objetos em respostas de API (JSON)

Muitos dados trafegam na web em formato JSON, que é essencialmente **texto representando objetos e arrays**, frequentemente com objetos aninhados.

Por exemplo, uma API pode retornar algo assim:

json
{
“usuario”: {
“id”: 1,
“nome”: “Ana”,
“endereco”: {
“cidade”: “São Paulo”,
“estado”: “SP”
}
}
}

Ao receber essa resposta em JavaScript (depois de fazer `JSON.parse()` ou usando `response.json()` no `fetch`), você terá um **objeto de objeto** exatamente como vimos:

js
const dados = {
usuario: {
id: 1,
nome: “Ana”,
endereco: {
cidade: “São Paulo”,
estado: “SP”
}
}
};

console.log(dados.usuario.endereco.cidade); // “São Paulo”

## 11. Boas práticas ao trabalhar com objetos aninhados

### 11.1. Evite aninhamento excessivo

Objetos com muitos níveis dificultam a leitura e manutenção:

js
// Evite algo assim:
sistema.usuario.configuracoes.interface.tema.cores.primaria;

Considere:

– Quebrar em estruturas menores
– Criar funções de acesso
– Normalizar dados, dependendo do caso

### 11.2. Use destructuring para simplificar

O **destructuring** ajuda a “desmontar” objetos aninhados:

js
const sistema = {
usuario: {
dadosPessoais: {
nome: “Ana”,
idade: 28
}
}
};

const { usuario: { dadosPessoais: { nome, idade } } } = sistema;

console.log(nome); // “Ana”
console.log(idade); // 28

Com `?.`:

js
const nomeUsuario = sistema.usuario?.dadosPessoais?.nome ?? “Desconhecido”;

### 11.3. Valide antes de acessar

Mesmo sem `?.`, você pode validar manualmente:

js
if (usuario && usuario.endereco && usuario.endereco.cidade) {
console.log(usuario.endereco.cidade);
}

## 12. Representando visualmente objetos aninhados

Diagrama em camadas demonstrando múltiplos níveis de objetos aninhados em JavaScript
Objetos aninhados podem ter vários níveis; cada nível é apenas mais um objeto referenciado por uma chave

Ver objetos aninhados como “camadas” ou “caixas dentro de caixas” ajuda a entender:

– Cada camada é um objeto
– Cada chave aponta para um valor, que pode ser outro objeto
– Navegar até uma informação é seguir esse caminho de chaves

## 13. Resumo

– Em JavaScript, `object` é um tipo que representa coleções de pares chave → valor.
– Um **objeto de objeto** é apenas um objeto que contém outro objeto em uma de suas propriedades.
– Acesso a objetos aninhados é feito encadeando chaves: `obj.chave1.chave2…`.
– É preciso ter cuidado com:
– Acesso a propriedades de valores `undefined`
– Cópia de objetos (referência vs cópia rasa vs cópia profunda)
– Ferramentas como `?.`, destructuring e uma boa modelagem de dados ajudam a manter o código mais seguro, legível e fácil de manter.

Entender bem esses conceitos é fundamental para trabalhar com dados estruturados em JavaScript, especialmente quando você lida com APIs, configurações complexas e modelagem de domínios de negócio.

Tem uma ideia ou projeto? Vamos conversar!

Seus dados estão seguros