Skip to content

5. Objetos literais

Aqui, referimo-nos aos objetos definidos literalmente no código como «objetos literais». O JavaScript possui o conceito de classes e objetos de instância de classe. Portanto, este não é o tipo de objeto que estamos a discutir agora.

Image

5.1. script [obj-01]

Apresentamos aqui as propriedades básicas dos objetos literais. A principal é que o objeto é manipulado através de um ponteiro.


'use strict';
// an empty object
const obj1={};
// object properties can be dynamically created
obj1.prop1="abcd";
console.log('obj1=',obj1);
// other property
obj1.prop2=[1,2,3];
console.log("obj1=",obj1);
// another property with a different notation
obj1['prop3']=true;
console.log("obj1=",obj1);
// obj1 is a reference to the object (pointer), not the object itself
const obj2=obj1;
// obj2 and obj1 point to the same object
obj2.prop1="xyzt";
console.log("obj1=",obj1);
console.log("obj2=",obj2);
// properties can be variables
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. A modificação do objeto para o qual o ponteiro aponta não altera o próprio ponteiro [obj1]. É por isso que, tal como acontece com as matrizes, uma referência a um objeto é declarada utilizando a palavra-chave [const];
  • Linha 6 do código: Tal como acontece com as matrizes, [console.log] pode 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 da referência ao objeto e não do próprio objeto;

5.2. script [obj-02]

Este script demonstra que as propriedades de um objeto podem ter um objeto como seu valor. Isto resulta em objetos de vários níveis. Também apresentamos o objeto global [JSON], que permite conversões de objeto para string e de string para objeto.


'use strict';
// a multi-level object
const personne = {
  prénom: "martin",
  âge: 12,
  père: {
    prénom: "paul",
    âge: 45
  },
  mère: {
    prénom: "micheline",
    âge: 42
  }
}
// access to properties
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 can display objects
console.log("personne=", personne);
console.log("mère=", personne.mère);
// you can also display the jSON string of the
let json = JSON.stringify(personne);
console.log("jSON=", json);
// you can reread the jSON
let personne2 = JSON.parse(json);
console.log("père=", personne2.père);

Comentários

  • linha 24: conversão de um objeto JavaScript numa cadeia JSON;
  • linha 27: conversão de uma string 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',
'âge': 12,
'père': { 'prénom': 'paul', 'âge': 45 },
'mère': { 'prénom': 'micheline', 'âge': 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 JSON, as propriedades devem estar entre aspas, tal como os valores das cadeias;

5.3. script [obj-03]

Este script apresenta o conceito de getters e setters para a propriedade de um objeto:


'use strict';
// object getters and setters
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);
// the object itself
console.log("personne=", personne);
// this does not prevent direct access to property [_nom]
personne._nom = "xyz";
console.log("personne=", personne);

Comentários

  • linhas 5–7: definição de um [getter], uma função que geralmente devolve o valor da propriedade de um objeto, mas que, na verdade, pode devolver qualquer coisa. A palavra-chave [function] é substituída pela palavra-chave [get];
  • linha 7: o getter retorna a propriedade [_name]. Note que esta propriedade não precisa de ser declarada;
  • linhas 10–13: definição de um [setter], uma função que geralmente 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]. O [setter] pode ser usado para validar o valor passado como parâmetro ao [setter];
  • linha 16: a função [set name] será chamada implicitamente;
  • linha 18: a função [get name] será chamada implicitamente;
  • linha 22: mostra que o uso de getters/setters depende do critério do programador. Se o programador souber o nome da propriedade gerida por eles, 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' }

Observe as linhas 5–6: [console.log] também exibe 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';
// object property names may be literal [name], surrounded by apostrophes ['name'], or may have a double quotation mark ['name']
// or quotation marks ["name"]
 
// literal
const obj1 = {
  nom: "martin",
  prénom: "jean"
};
console.log("prénom=", obj1.prénom);
 
// surrounded by apostrophes
const obj2 = {
  'nom': "martin",
  'prénom': "jean"
};
console.log("nom=", obj2.nom);
 
// surrounded by quotation marks
const obj3 = {
  "nom": "martin",
  "prénom": "jean"
};
 
// two possible syntaxes for accessing the [name] property
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. Isto é muito semelhante a um objeto de instância de classe, que possui propriedades e métodos.


'use strict';
 
// an object can have properties of type [function]
const personne = {
  // properties
  prénom: "martin",
  âge: 12,
  père: {
    prénom: "paul",
    âge: 45
  },
  mère: {
    prénom: "micheline",
    âge: 42
  },
  // method
  toString: function () {
    return JSON.stringify(this);
  }
}
 
// use
console.log("personne=", personne);
console.log("personne.toString=", personne.toString());
  • linhas 17–19: um método interno do objeto. Neste método, acedemos às propriedades do objeto utilizando a palavra-chave [this] (linha 18). [this] refere-se ao próprio objeto, e [this.firstName] refere-se à sua propriedade [firstName];

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',
'âge': 12,
'père': { 'prénom': 'paul', 'âge': 45 },
'mère': { 'prénom': 'micheline', 'âge': 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 demonstra como aceder às propriedades de um objeto quando os seus nomes não são conhecidos antecipadamente.


'use strict';
 
// an object can have properties of type [function]
let personne = {
  // properties
  prénom: "martin",
  âge: 12,
  père: {
    prénom: "paul",
    âge: 45
  },
  mère: {
    prénom: "micheline",
    âge: 42
  },
  // method
  toString: function () {
    return JSON.stringify(this);
  }
}
 
// use
console.log(personne);
// properties
console.log("-----------------------");
for (const key in personne) {
  if (personne.hasOwnProperty(key)) {
    const element = personne[key];
    console.log(key, "=", element);
  }
}
// to escape the eslint warning (1)
console.log("-----------------------");
for (const key in personne) {
  if (Object.prototype.hasOwnProperty.call(personne, key)) {
    const element = personne[key];
    console.log(key, "=", element);
  }
}
// to escape the eslint warning (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 recupera a lista de propriedades (excluindo métodos) de um objeto. Este código aciona um aviso do ESLint:

Image

  • linhas 32–39: o código que nos permite ignorar o aviso do ESLint. Utilizamos o protótipo da classe [Object];
  • linhas 41–47: ou podemos simplesmente desativar o aviso (linha 43);

5.7. script [obj-07]

O script [obj-07] demonstra a capacidade de destruir um objeto:


'use strict';
// destructuring
 
// literal
const obj1 = {
  nom: "martin",
  prénom: "jean"
};
 
// destructuring obj1 into variables [n,p]
const { nom: n, prénom: p } = obj1;
console.log("n=", n, "p=", p);
 
// destructure obj1 in variables [n2,p2]
function f({ nom: n2, prénom: p2 }) {
  console.log("f-n2=", n2, "f-p2=", p2);
}
f(obj1);
 
// destructuring obj1 into variables [last name,first name]
function g({ nom: nom, prénom: prénom }) {
  console.log("g-nom=", nom, "g-prénom=", prénom);
}
g(obj1);
 
// destructuring obj1 into variables [last name,first name]
// with shortened notation equivalent to h({name:surname,firstname:firstname})
function h({ nom, prénom }) {
  console.log("h-nom=", nom, "h-prénom=", prénom);
}
h(obj1);

Comentários

  • linha 11: as chaves {} 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 escrita da seguinte forma:


const { nom => n, prénom => p } = obj1

para indicar que os valores dos atributos [lastName, firstName] são atribuídos às variáveis [n, p];

  • a operação de desestruturação é repetida nas linhas 15, 21 e 28. Em cada uma delas, a presença de chaves {} indica que um objeto será desestruturado em variáveis;
  • A linha 28 pode ser confusa. É uma forma abreviada da notação:

function h({ nom : nom, prénom : prénom })

Os resultados da execução são os seguintes:

1
2
3
4
n= martin p= jean
f-n2= martin f-p2= jean
g-nom= martin g-prénom= jean
h-nom= martin h-prénom= jean

5.8. script [obj-08]

O script [obj-08] mostra como obter uma cópia de um objeto:


'use strict'
 
// object cloning
const obj1 = {
  nom: "martin",
  prénom: "jean"
};
 
// clone (copy) of obj1 with the spread operator
const obj2 = { ...obj1 }
 
// checks
// obj2 points to a copy of obj1
console.log("obj2===obj1 :", obj1 === obj2)
console.log("obj2=", obj2)
  • linha 10: a operação para copiar o objeto [obj1]. O operador ... é chamado de operador de expansão;

Os resultados da execução são os seguintes:

obj2===obj1 : false
obj2= { nom: 'martin', 'prénom': 'jean' }
  • linha 1: mostra que as referências [obj1] e [obj2] não apontam para o mesmo objeto;
  • linha 2: mostra que o objeto apontado por [obj2] é uma cópia do objeto apontado por [obj1];

5.9. Conclusão

Os scripts desta secção demonstraram que o objeto literal do JavaScript é semelhante ao objeto de instância de classe nas linguagens orientadas para objetos. É possível definir propriedades, métodos e getters/setters nele. Trata-se de um objeto dinâmico cujas propriedades podem ser definidas em tempo de execução. Comporta-se, então, como um dicionário cujos elementos podem ser de qualquer tipo, incluindo o tipo [função].