Do que é feito um Objeto em JavaScript?

27 de janeiro de 2026 • JavaScript, Resumo

Antes de falarmos sobre como objetos funcionam eu preciso explicar o que é um objeto.

Um objeto é uma coleção de dados que vou chamar de propriedades, onde cada propriedade é uma associação entre uma chave e um valor. Esses valores podem ser de qualquer tipo, incluindo outros objetos, funções, arrays, etc.

Um array em JavaScript também é um tipo de objeto, mas com algumas características especiais, por ser estruturado para armazenar os valores em uma ordem específica e permitir o acesso a esses valores de forma ordenada.

O Array do JavaScript está mais proximo de uma Linked List do que um Array tradicional de outras linguagens, porque na memoria ele não fica verdadeiramente ordenado.

Vou usar esse objeto e essa lista como exemplo adiante:

const objeto = { 
    nome: 'Batata',
    quantidade: 5,
    preco: 10.99 
};
 
const lista = [1, 2, 3, 4, 5]; 

Quando declaramos uma variável como um objeto, estamos criando uma referência para esse objeto na memória, e não o valor em si como acontece com os tipos primitivos.

Portanto a váriavel do objeto guarda apenas a referencia para o local na memória onde o objeto está armazenado.

Sendo assim um objeto declarado com const ainda sim pode ter suas propriedades alteradas, porque a váriavel apenas guarda o endereço do objeto na memória, e não o objeto em si.

Tipos Primitivos

-> Number
-> String
-> Boolean
-> null
-> undefined
-> BigInt
-> Symbol

No JavaScript tudo que não é um tipo primitivo é um objeto.

Inicialmente o JavaScript foi projetado para ser uma linguagem de script e não uma de uso geral como é hoje em dia, então para fazer heranças no JavaScript foi usando estrategia de protótipos.

Todo objeto criado no JavaScript tem uma referência interna para seu protótipo, que é outro objeto, para simplificar, é como se esse objeto fosse o "pai". De qual ele adquire a herança que são seus métodos e propriedades.

Exemplos:

Criando um objeto:

console.log(Object.getPrototypeOf(objeto) === Object.prototype); // true

Criando um array:

console.log(Object.getPrototypeOf(lista) === Array.prototype); // true

Por ter essa referência para o protótipo, o JavaScript cria uma cadeia de protótipos, assim quando acessamos uma propriedade ou método de um objeto, o JavaScript primeiro procura essa propriedade ou método no próprio objeto, se não encontrar ele procura no protótipo do objeto, se não encontrar lá ele procura no protótipo do protótipo e assim por diante até chegar no topo da cadeia de protótipos que é o Object.prototype.

console.log(lista.hasOwnProperty('length')); // true
console.log(Object.getPrototypeOf(lista) === Array.prototype); // true
console.log(Object.getPrototypeOf(Array.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

Object.Prototype está no topo da cadeia, e tem a implementação do método toString que é herdado por todos os objetos, mas cada tipo de objeto pode ter sua própria implementação desse método.

Por exemplo o método toString do Array.prototype é diferente do método toString do Object.prototype.

console.log(lista.toString()); // "1,2,3,4,5"
console.log(objeto.toString()); // "[object Object]"

O que acontece é que o método toString do Array.prototype sobrescreve o método toString do Object.prototype.

Internamente o Array.prototype.toString chama o método join para juntar os elementos do array em uma string.

Provando que são métodos diferentes:

console.log(Array.prototype.toString === Object.prototype.toString); // false

Provando que ele chama o join:

console.log(Array.prototype.toString.call({ join: () => "batata" })); // "batata"

Bonus:

Cópia rasa x Cópia profunda

Cópia rasa (shallow copy):

const copiaRasa = { ...objeto };

Cópia profunda (deep copy):

const copiaProfunda = JSON.parse(JSON.stringify(objeto));

Como dito anteriormente uma variável não guarda o objeto em si e sim uma referência, assim como dentro do objeto ele pode ter uma propriedade que guarda a referência para outro objeto, então quando copiamos um objeto de forma rasa, estamos copiando apenas a referência para os objetos internos, assim se alterarmos um objeto interno na copia ele também será alterado no objeto original.

Porem da forma profunda, estamos criando um novo objeto completamente indepentendete do original, com as suas prorpias referências

Só que dessa forma a cópia profunda tem suas limitações, como por exemplo não copiar funções, símbolos, propriedades que armazenam undefined, entre outros, já que ele está convertendo o objeto para uma string JSON e depois de volta para um objeto.

Para realmente fazer uma copia profunda sem essas limitações, precisamos usar bibliotecas como Lodash ou escrever nossa própria função de cópia profunda.