Além dos tipos de dados primitivos como number e string, existe em JavaScript outro tipo de dados importante chamado object.
Os objetos são coleções de pares chave-valor.
Como tal, podem ser usados como aquilo a que noutras linguagens se costuma chamar mapas ou dicionários.
Noutras linguagens, todos os valores de um mapa têm muitas vezes de ter o mesmo tipo de dados. Em JavaScript, apenas o tipo da chave está restringido: tem de ser uma string. Os valores dentro de um mesmo objeto podem ter tipos diferentes. Podem ser tipos primitivos como números, mas também arrays, outros objetos ou até funções. Isto torna os objetos muito versáteis, o que faz deles também entidades centrais para a programação orientada a objetos (POO) em JavaScript.
De seguida, vamos focar-nos nos objetos enquanto coleções ou mapas. Outros casos de utilização dos objetos serão abordados noutros conceitos, vê por exemplo Classes.
Crias um objeto literal com chavetas. Também podes incluir diretamente algumas entradas (pares chave-valor). Para isso, indica primeiro a chave, seguida de dois pontos e do valor.
const emptyObject = {};
const obj = {
favoriteNumber: 42,
greeting: 'Hello World',
useGreeting: true,
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
fruits: ['melon', 'papaya'],
addNumbers: function (a, b) {
return a + b;
},
};
A vírgula final depois da última entrada é opcional em JavaScript. Podes ler sobre as vantagens de a usar aqui.
Podes perguntar-te porque é que as chaves não estão entre aspas, apesar de se supor que são strings. Isto é uma notação abreviada. Se a chave seguir as regras de nomenclatura de um identificador de JavaScript, podes omitir as aspas. Para chaves com carateres especiais no nome, tens de usar a notação de string habitual.
const obj = {
'1keyStartsWithNumber': '...',
'key/with/slashes': '...',
'key-with-dashes': '...',
'key with spaces': '...',
'#&()[]{}èä樹keyWithSpecialChars': '...',
};
Muitas vezes vais querer adicionar variáveis existentes quando declaras um objeto.
Isso levaria frequentemente a pares chave-valor como name: name.
JavaScript tem uma notação abreviada que permite escrever apenas name.
Há também uma notação abreviada para definir uma função num objeto.
Aí podes omitir os dois pontos e a palavra-chave function.
const x = 1;
const y = 2;
const obj = {
x: x,
y: y,
calcSum: function (a, b) {
return a + b;
},
};
// Can be shortened to ...
const obj = {
x,
y,
calcSum(a, b) {
return a + b;
},
};
Se quiseres criar um objeto literal com um nome de chave que está guardado numa variável ou obtido através de uma expressão, tens de colocar a variável ou a expressão entre parênteses retos.
const key = 'greeting';
const obj = {
[key]: 'hello world',
};
console.log(obj);
// => { greeting: 'hello world' }
Há duas formas de obter o valor de uma determinada chave: a notação de ponto e a notação de parênteses retos.
const obj = { greeting: 'hello world' };
obj.greeting;
// => hello world
obj['greeting'];
// => hello world
// Bracket notation also works with variables.
const key = 'greeting';
obj[key];
// => hello world
Usar a notação de ponto como forma abreviada tem a mesma restrição que omitir as aspas. Só funciona se a chave seguir as regras de nomenclatura de identificadores.
Se tentares obter uma chave que não existe no objeto, o JavaScript devolve undefined.
Vê Null e Undefined para mais detalhes sobre isto.
Podes encadear as chaves se quiseres obter um valor de um objeto aninhado.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.address.city;
// => 'Batticaloa'
obj['address']['city'];
// => 'Batticaloa'
// Notations can also be mixed.
obj.address['city'];
// => 'Batticaloa'
Podes adicionar ou alterar um valor com o operador de atribuição =.
Mais uma vez, tens à disposição a notação de ponto e a de parênteses retos.
const obj = { greeting: 'hello world' };
obj.greeting = 'Hi there!';
obj['greeting'] = 'Welcome.';
obj.newKey1 = 'new value 1';
obj['new key 2'] = 'new value 2';
const key = 'new key 3';
obj[key] = 'new value 3';
Podes eliminar um par chave-valor de um objeto com a palavra-chave delete.
const obj = {
key1: 'value1',
key2: 'value2',
};
delete obj.key1;
delete obj['key2'];
Repara que, embora undefined seja devolvido para chaves inexistentes, definir uma chave como undefined não remove a entrada.
Usa sempre delete em vez disso.
Podes verificar se uma determinada chave existe num objeto com o método hasOwnProperty.
const obj = { greeting: 'hello world' };
obj.hasOwnProperty('greeting');
// => true
obj.hasOwnProperty('age');
// => false
hasOwnProperty devolve false para chaves herdadas. Este é habitualmente o comportamento desejado.
Se quiseres incluir chaves herdadas na verificação de existência, podes usar antes o operador in.
Há um ciclo for...in especial para iterar sobre todas as chaves de um objeto.
const obj = {
name: 'Ali',
age: 65,
};
for (let key in obj) {
console.log(key, obj[key]);
}
// name Ali
// age 65
Pode parecer que o for...in visita sempre as chaves pela ordem em que aparecem ou foram adicionadas ao objeto (ordem de inserção).
No entanto, não deves contar com isso, porque há casos especiais em que a ordem difere da ordem de inserção.
Escreve sempre o teu código como se a ordem fosse arbitrária.
Se precisares de uma ordem fiável, usa antes um Map ou um [array][concept-arrays] aninhado em vez de um objeto.
O ciclo for…in tem uma armadilha quando o objeto tem chaves herdadas.
Essas também serão visitadas pelo ciclo for…in.
Normalmente queres evitar isso, por isso tens de as saltar como mostrado abaixo.
for (let key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
// ...
}
O JavaScript também tem um ciclo for...of, por exemplo para iterar sobre arrays.
É importante notar que for...in e for...of não são intercambiáveis; vê a documentação da MDN para mais detalhes sobre isto.
O objeto incorporado Object fornece métodos auxiliares para obter todas as chaves, valores ou entradas de um determinado objeto como arrays.
const obj = {
name: 'Ali',
age: 65,
};
Object.keys(obj);
// => [ 'name', 'age' ]
Object.values(obj);
// => [ 'Ali', 65 ]
Object.entries(obj);
// => [ [ 'name', 'Ali' ], [ 'age', 65 ] ]
Talvez tenhas reparado que um objeto vazio em JavaScript não está completamente vazio.
Por exemplo, contém o método hasOwnProperty e outros métodos como toString.
Normalmente, isso não causa problemas, mas se alguma vez precisares de criar um objeto realmente vazio, usa um objeto nulo que pode ser criado através de Object.create(null).