5. Os objetos literais
Chamamos aqui de «objetos literais» os objetos definidos literalmente no código. O JavaScript tem o conceito de classe e de objeto instância de classe. Não é, portanto, deste tipo de objeto que estamos a falar agora.

5.1. script [obj-01]
Apresentamos aqui as principais propriedades dos objetos literais. A principal é que o objeto é manipulado através de um ponteiro.
'use strict';
// um objeto vazio
const obj1={};
// é possível criar dinamicamente as propriedades do objeto
obj1.prop1="abcd";
console.log('obj1=',obj1);
// outra propriedade
obj1.prop2=[1,2,3];
console.log("obj1=",obj1);
// outra propriedade com uma notação diferente
obj1['prop3']=true;
console.log("obj1=",obj1);
// obj1 é uma referência ao objeto (ponteiro), não o próprio objeto
const obj2=obj1;
// obj2 e obj1 apontam para o mesmo objeto
obj2.prop1="xyzt";
console.log("obj1=",obj1);
console.log("obj2=",obj2);
// as propriedades podem ser variáveis
const var1='prop1';
console.log('prop1=',obj1[var1]);
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-01.js"
obj1=[object Object]
obj1= { prop1: 'abcd', prop2: [ 1, 2, 3 ] }
obj1= { prop1: 'abcd', prop2: [ 1, 2, 3 ], prop3: true }
obj1= { prop1: 'xyzt', prop2: [ 1, 2, 3 ], prop3: true }
obj2= { prop1: 'xyzt', prop2: [ 1, 2, 3 ], prop3: true }
prop1= xyzt
Comentários
- linha 3 do código: um objeto é manipulado através de um ponteiro. Portanto, [obj1] é um ponteiro. Alterar o objeto apontado não altera o ponteiro [obj1]. É por isso que, tal como acontece com os tabuletos, é declarada uma referência de objeto com a palavra-chave [const];
- linha 6 do código: tal como acontece com os tabuletos, [console.log] sabe apresentar objetos;
- linha 11 do código: obj1.prop3 pode ser reescrito como obj1.[‘prop3’]. Esta última notação é útil quando «prop3» é, na verdade, uma variável (linhas 20-21);
- linhas 13-18 do código: mostram que a instrução [obj2=obj1] é uma cópia por referência do objeto e não do próprio objeto;
5.2. script [obj-02]
Este script mostra que as propriedades de um objeto podem ter como valor um objeto. Temos, assim, objetos multiníveis. Introduzimos também o objeto global [JSON], que permite efetuar conversões objeto ↔ cadeia de caracteres.
''use strict';
// um objeto com vários níveis
const personne = {
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
}
}
// acesso às propriedades
console.log("prénom personne=", personne.prénom);
console.log("prénom mère=", personne.mère.prénom);
personne.mère.âge = 40;
console.log("âge mère=", personne.mère.âge);
// console.log sabe apresentar objetos
console.log("personne=", personne);
console.log("mère=", personne.mère);
// também é possível exibir a cadeia jSON do objeto
let json = JSON.stringify(personne);
console.log("jSON=", json);
// é possível ler novamente o jSON
let personne2 = JSON.parse(json);
console.log("père=", personne2.père);
Comentários
- linha 24: transformação de um objeto JavaScript numa cadeia de caracteres jSON;
- linha 27: transformação de uma cadeia de caracteres jSON num objeto JavaScript;
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-02.js"
prénom personne= martin
prénom mère= micheline
âge mère= 40
personne= { 'prénom': 'martin',
'idade': 12,
'pai': { 'nome': 'paul', 'idade': 45 },
'mãe': { 'nome': 'micheline', 'idade': 40 } }
mère= { 'prénom': 'micheline', 'âge': 40 }
jSON= {"prénom":"martin","âge":12,"père":{"prénom":"paul","âge":45},"mère":{"prénom":"micheline","âge":40}}
père= { 'prénom': 'paul', 'âge': 45 }
Comentários
- linha 10: numa cadeia de caracteres jSON, as propriedades têm de estar entre aspas, tal como os valores do tipo cadeia de caracteres;
5.3. script [obj-03]
Este script introduz o conceito de getter/setter de uma propriedade de um objeto:
'use strict';
// getters e setters de um objeto
const personne = {
// getter
get nom() {
console.log("getter nom");
return this._nom;
},
// setter
set nom(unNom) {
console.log("setter nom");
this._nom = unNom;
}
};
// setter
personne.nom = "Hercule";
// getter
console.log(personne.nom);
// o próprio objeto
console.log("personne=", personne);
// isso não impede o acesso direto à propriedade [_nom]
personne._nom = "xyz";
console.log("personne=", personne);
Comentários
- linhas 5-7: definição de uma função [getter], que geralmente devolve o valor de uma propriedade do objeto, mas que, na verdade, pode devolver qualquer coisa. A palavra-chave [function] é substituída pela palavra-chave [get];
- linha 7: o getter devolve a propriedade [_nom]. Vê-se que esta não precisa de ser declarada;
- linhas 10-13: definição de uma função [setter], que normalmente atribui o valor recebido a uma propriedade do objeto, mas que, na verdade, pode fazer qualquer coisa. A palavra-chave [function] é substituída pela palavra-chave [set]. A função [setter] pode ser utilizada para verificar a validade do valor passado como parâmetro à função [setter];
- linha 16: a função [set nom] será chamada implicitamente;
- linha 18: a função [get nom] será chamada implicitamente;
- linha 22: mostra que a utilização dos getter/setter depende da boa vontade do programador. Se este conhecer o nome da propriedade gerida por estes, pode aceder-lhe diretamente;
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-03.js"
setter nom
getter nom
Hercule
personne= { nom: [Getter/Setter], _nom: 'Hercule' }
personne= { nom: [Getter/Setter], _nom: 'xyz' }
Note-se, nas linhas 5-6, que [console.log] também apresenta as propriedades que são funções.
5.4. script [obj-04]
Este script mostra três formas de escrever os nomes das propriedades de um objeto e duas formas de aceder às mesmas.
'use strict';
// os nomes das propriedades de um objeto podem ser literais [nom], estar entre apóstrofos ['nom']
// ou entre aspas duplas ["nom"]
// literais
const obj1 = {
nom: "martin",
prénom: "jean"
};
console.log("prénom=", obj1.prénom);
// entre apóstrofos
const obj2 = {
'nome': "martin",
'apelido': "jean"
};
console.log("nom=", obj2.nom);
// entre aspas
const obj3 = {
"nom": "martin",
"prénom": "jean"
};
// duas sintaxes possíveis para aceder à propriedade [nom]
console.log("nom=", obj3.nom);
console.log("nom=", obj3['nom']);
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-04.js"
prénom= jean
nom= martin
nom= martin
nom= martin
5.5. script [obj-05]
O script mostra que as propriedades de um objeto literal podem ser funções. Estamos, assim, muito próximos do objeto instância de classe, onde temos propriedades e métodos.
'use strict';
// um objeto pode ter propriedades do tipo [function]
const personne = {
// propriedades
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
},
// método
toString: function () {
return JSON.stringify(this);
}
}
// utilização
console.log("personne=", personne);
console.log("personne.toString=", personne.toString());
- linhas 17-19: um método interno do objeto. Neste método, acede-se às propriedades do objeto através da palavra-chave [this] (linha 18). [this] designa o próprio objeto, [this.prénom], a propriedade [prénom] deste;
Execução
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe "c:\Temp\19-09-01\javascript\objets\obj-05.js"
personne= { 'prénom': 'martin',
'idade': 12,
'pai': { 'nome': 'paul', 'idade': 45 },
'mãe': { 'nome': 'micheline', 'idade': 42 },
toString: [Function: toString] }
personne.toString= {"prénom":"martin","âge":12,"père":{"prénom":"paul","âge":45},"mère":{"prénom":"micheline","âge":42}}
5.6. script [obj-06]
Este script mostra como aceder às propriedades de um objeto quando não se conhece previamente o nome dessas propriedades.
'use strict';
// um objeto pode ter propriedades do tipo [function]
let personne = {
// propriedades
prénom: "martin",
âge: 12,
père: {
prénom: "paul",
âge: 45
},
mère: {
prénom: "micheline",
âge: 42
},
// método
toString: function () {
return JSON.stringify(this);
}
}
// utilização
console.log(personne);
// propriedades
console.log("-----------------------");
for (const key in personne) {
if (personne.hasOwnProperty(key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
// para evitar o aviso do ESLint (1)
console.log("-----------------------");
for (const key in personne) {
if (Object.prototype.hasOwnProperty.call(personne, key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
// para evitar o aviso do ESLint (2)
console.log("-----------------------");
for (const key in personne) {
// eslint-disable-next-line no-prototype-builtins
if (personne.hasOwnProperty(key)) {
const element = personne[key];
console.log(key, "=", element);
}
}
Comentários
- linhas 26-31: o código que permite obter a lista de propriedades, sem os métodos, de um objeto. Este código é objeto de um aviso de ESLint:

- linhas 32-39: o código que permite contornar o aviso de ESLint. Recorre-se ao protótipo da classe [Object];
- linhas 41-47: ou simplesmente desativamos o aviso (linha 43);
5.7. script [obj-07]
O script [obj-07] mostra a possibilidade de desestruturar um objeto:
'use strict';
// desestruturação
// literais
const obj1 = {
nom: "martin",
prénom: "jean"
};
// desestruturação de obj1 em variáveis [n,p]
const { nom: n, prénom: p } = obj1;
console.log("n=", n, "p=", p);
// desestruturação de obj1 em variáveis [n2,p2]
function f({ nom: n2, prénom: p2 }) {
console.log("f-n2=", n2, "f-p2=", p2);
}
f(obj1);
// desestruturação de obj1 em variáveis [nom,prénom]
function g({ nom: nom, prénom: prénom }) {
console.log("g-nom=", nom, "g-prénom=", prénom);
}
g(obj1);
// desestruturação de obj1 em variáveis [nom,prénom]
// com notação abreviada equivalente a h({nome:nome,apelido:apelido})
function h({ nom, prénom }) {
console.log("h-nom=", nom, "h-prénom=", prénom);
}
h(obj1);
Comentários
- linha 11: são as chaves {} que permitem a desestruturação. A sintaxe
const { nom: n, prénom: p } = obj1
cria duas variáveis, [n] e [p], e é equivalente a:
const n = obj1.nom
const p = obj1.prénom
A declaração poderia ser lida da seguinte forma:
const { nom => n, prénom => p } = obj1
para recordar que os valores dos atributos [nom, prénom] são atribuídos às variáveis [n, p];
- a operação de desestruturação repete-se nas linhas 15, 21 e 28. Em cada caso, é a presença das chaves {} que indica que haverá desestruturação de um objeto em variáveis;
- a linha 28 pode ser confusa. Trata-se de um atalho para a notação:
function h({ nom : nom, prénom : prénom })
Os resultados da execução são os seguintes:
5.8. script [obj-08]
O script [obj-08] mostra como obter uma cópia de um objeto:
'use strict'
// clonagem de objetos
const obj1 = {
nom: "martin",
prénom: "jean"
};
// clona (copia) obj1 com o operador de expansão
const obj2 = { ...obj1 }
// verificações
// obj2 aponta para uma cópia de obj1
console.log("obj2===obj1 :", obj1 === obj2)
console.log("obj2=", obj2)
- linha 10: a operação de cópia do objeto [obj1]. O operador ... é denominado operador de spread;
Os resultados da execução são os seguintes:
- linha 1: mostra que as referências [obj1] e [obj2] não apontam para o mesmo objeto;
- linha 2: mostra que o objeto a que aponta [obj2] é uma cópia do objeto a que aponta [obj1];
5.9. Conclusion
Os scripts desta secção demonstraram que o objeto literal do JavaScript é semelhante ao objeto de instância de classe das linguagens orientadas para objetos. É possível definir nele propriedades, métodos e getters/setters. Trata-se de um objeto dinâmico cujas propriedades podem ser definidas em tempo de execução. Comporta-se, assim, como um dicionário cujos elementos podem ser de qualquer tipo, nomeadamente do tipo [fonction].