Inicializador de Objeto

Objetos podem ser inicializados utilizando new Object(), Object.create(), ou a notação literal. Um inicializador de objetos é uma lista de zero ou mais pares de propriedade: valor, separados por vírgula e fechado por um par de chaves ({}).

Sintaxe

js
var o = {};
var o = { a: "foo", b: 42, c: {} };

var a = "foo",
  b = 42,
  c = {};
var o = { a: a, b: b, c: c };

var o = {
  propriedade: function ([parâmetros]) {},
  get propriedade() {},
  set propriedade(valor) {},
};

Novas notações em ECMAScript 2015

Por favor, verifique o suporte das anotações na tabela de compatibilidade. Em ambientes que não dão suporte às anotações, ocorrerá erros de sintaxe.

js
// // Abreviação em nomes de propriedades (ES2015)
var a = "foo",
  b = 42,
  c = {};
var o = { a, b, c };

// // Abreviação em nomes de métodos (ES2015)
var o = {
  property([parameters]) {},
  get property() {},
  set property(value) {},
};

// Nomes de propriedades computados (ES2015)
var prop = "foo";
var o = {
  [prop]: "hey",
  ["b" + "ar"]: "there",
};

Descrição

Um inicializador de objetos é uma expressão que descreve a inicialização de um Object. Objects consiste de propriedades, as quais descrevem um objeto. Os valores das propriedades de um objeto podem ser tipos de dados primitivos ou outros objetos .

Criando objetos

Um objeto vazio, sem propriedades, pode ser criado como:

js
var object = {};

Contudo, a vantagem em utilizar a notação literal ou o inicializador é a possibilidade de rapidamente criar objetos com propriedades dentro de chaves ({}). Você simplesmente cria uma lista de pares chave: valor, separados por vírgula. O código abaixo cria um objeto com três propriedades, sendo as chaves "foo", "age" e "baz", com seus respectivos valores, tipo string de valor "bar", tipo number de valor 42 e, por último, um outro objeto com seus respectivos pares de chave: valor.

js
var object = {
  foo: "bar",
  age: 42,
  baz: { myProp: 12 },
};

Acessando propriedades

Uma vez que você criou um objeto, é interessante que possa ler ou alterá-lo. As propriedades de um objeto podem ser acessadas utilizando a notação de ponto ou colchetes. Veja assessores de propriedade para mais informações.

js
object.foo; // "bar"
object["age"]; // 42

object.foo = "baz";

Definições de propriedade

Nós temos aprendido como descrever propriedades utilizando a sintaxe inicializador. No entanto, às vezes, há variáveis que queremos inserir em nosso objeto. Então teremos um código parecido como abaixo:

js
var a = "foo",
  b = 42,
  c = {};

var o = {
  a: a,
  b: b,
  c: c,
};

Com ECMAScript 2015, há uma notação mais curta que possibilita atingir o mesmo resultado:

js
var a = "foo",
  b = 42,
  c = {};

// Abreviação em nomes de propriedades (ES2015)
var o = { a, b, c };

// Em outras palavras,
console.log(o.a === { a }.a); // true

Duplicação em nomes de propriedades

Quando se está utilizando o mesmo nome para suas propriedades, a última sobrescreverá as anteriores.

js
var a = { x: 1, x: 2 };
console.log(a); // { x: 2}

Em códigos ECMAScript 5 no modo estrito, duplicação em nomes de propriedades serão consideradas SyntaxError (en-US). Porém, com a introdução de "nomes de propriedades computadas", tornou-se possível a duplicação das propriedades em tempo de execução. Assim, ECMAScript 2015 removeu a restrição.

js
function haveES2015DuplicatePropertySemantics() {
  "use strict";
  try {
    ({ prop: 1, prop: 2 });

    // No error thrown, duplicate property names allowed in strict mode
    return true;
  } catch (e) {
    // Error thrown, duplicates prohibited in strict mode
    return false;
  }
}

Definição de métodos

Uma propriedade de um objeto pode se referir à function, ou aos métodos getter ou setter.

js
var o = {
  propriedade: function ([parâmetros]) {},
  get propriedade() {},
  set propriedade(valor) {},
};

No ECMAScript 2015, uma notação abreviada está disponível, dispensando o uso da palavra reservada "function".

js
// Abreviações em nomes de métodos (ES2015)
var o = {
  propriedade([parâmetros]) {},
  get propriedade() {},
  set propriedade(valor) {},
  *gerador() {},
};

Com ECMAScript 2015, há uma forma concisa em criar propriedades cujo valor é uma função gerador.

js
var o = {
  * gerador() {
    ...........
  }
};

Mas em ECMAScript 5, você escreveria (lembrar que em ES5 não há geradores):

js
var o = {
  generator: function *() {
    ...........
  }
};

Para mais informações e exemplos, veja definições de método.

Nomes de propriedades computados

Começando com ECMAScript 2015, a sintaxe inicializador de objeto também suporta "nomes de propriedades computados". Isso permite que você possa inserir uma expressão dentro de colchetes [], que será computada como o nome de uma propriedade. Isto é semelhante à notação de chaves utilizado em acessor de propriedade, utilizado para ler a alterar as propriedades existentes em um objeto. Segue um exemplo utilizando a mesma sintaxe em objetos literais:

js
// Nomes de propriedades computados (ES2015)
var i = 0;
var a = {
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

var param = "size";
var config = {
  [param]: 12,
  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4,
};

console.log(config); // { size: 12, mobileSize: 4 }

Mutação Prototype

Uma definição de propriedade na forma de __proto__: valor or "__proto__": valor não cria uma propriedade com o nome __proto__. Inclusive, se o valor fornecido for um objeto ou null, muda o [[Prototype]] do objeto criado para o valor informado. (Se o valor fornecido não é um objeto ou null, o valor não será alterado.)

js
var obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);

var obj2 = { __proto__: null };
assert(Object.getPrototypeOf(obj2) === null);

var protoObj = {};
var obj3 = { __proto__: protoObj };
assert(Object.getPrototypeOf(obj3) === protoObj);

var obj4 = { __proto__: "not an object or null" };
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty("__proto__"));

Apenas uma única mudança em prototype é permitida em um objeto: múltiplas mudanças gera erro de sintaxe.

Definições de propriedade que não utilizam da notação de ":", não são consideradas mudanças de prototype: são definições de propriedades que se comportam de forma semelhante às definições utilizando qualquer outro nome.

js
var __proto__ = "variable";

var obj1 = { __proto__ };
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty("__proto__"));
assert(obj1.__proto__ === "variable");

var obj2 = {
  __proto__() {
    return "hello";
  },
};
assert(obj2.__proto__() === "hello");

var obj3 = { ["__prot" + "o__"]: 17 };
assert(obj3.__proto__ === 17);

Notação de objeto literal vs JSON

A notação de objeto literal não é a mesma de JavaScript Object Notation (JSON). Mesmo que possuam semelhanças, há as seguintes diferenças:

  • JSON permite definições de propriedades utilizando apenas aspas duplas, como "propriedade": valor. E a definição não pode ser abreviada.
  • Os valores JSON podem ser apenas strings, numbers, arrays, true, false, null, ou outro objeto JSON.
  • Uma função como valor (veja "Métodos" acima) não pode ser atribuido em JSON.
  • Objetos como Date serão do tipo string após JSON.parse().
  • JSON.parse() rejeitará "nomes de propriedades computados" e um erro será lançado.

Especificações

Specification
ECMAScript Language Specification
# sec-object-initializer

Compatibilidade com navegadores

BCD tables only load in the browser

Veja também