Web/JavaScript/Reference/Operators/Object initializer

From Get docs


Objects can be initialized using new Object()Object.create(), or using the literal notation (initializer notation). An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}).


The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

Syntax

let o = {}
let o = {a: 'foo', b: 42, c: {}}

let a = 'foo', b = 42, c = {}
let o = {a: a, b: b, c: c}

let o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {}
};

New notations in ECMAScript 2015

Please see the compatibility table for support for these notations. In non-supporting environments, these notations will lead to syntax errors.

// Shorthand property names (ES2015)
let a = 'foo', b = 42, c = {};
let o = {a, b, c}

// Shorthand method names (ES2015)
let o = {
  property(parameters) {}
}

// Computed property names (ES2015)
let prop = 'foo';
let o = {
  [prop]: 'hey',
  ['b' + 'ar']: 'there'
}

Description

An object initializer is an expression that describes the initialization of an Object. Objects consist of properties, which are used to describe an object. The values of object properties can either contain primitive data types or other objects.

Object literal notation vs JSON

The object literal notation is not the same as the JavaScript Object Notation (JSON). Although they look similar, there are differences between them:

  • JSON permits only property definition using "property": value syntax.  The property name must be double-quoted, and the definition cannot be a shorthand.
  • In JSON the values can only be strings, numbers, arrays, true, false, null, or another (JSON) object.
  • A function value (see "Methods" above) can not be assigned to a value in JSON.
  • Objects like Date will be a string after JSON.parse().
  • JSON.parse() will reject computed property names and an error will be thrown.

Examples

Creating objects

An empty object with no properties can be created like this:

let object = {}

However, the advantage of the literal or initializer notation is, that you are able to quickly create objects with properties inside the curly braces. You simply notate a list of key: value pairs delimited by commas.

The following code creates an object with three properties and the keys are "foo", "age" and "baz". The values of these keys are a string "bar", the number 42, and another object.

let object = {
  foo: 'bar',
  age: 42,
  baz: {myProp: 12}
}

Accessing properties

Once you have created an object, you might want to read or change them. Object properties can be accessed by using the dot notation or the bracket notation. (See property accessors for detailed information.)

object.foo // "bar"
object['age'] // 42

object.foo = 'baz'

Property definitions

We have already learned how to notate properties using the initializer syntax. Oftentimes, there are variables in your code that you would like to put into an object. You will see code like this:

let a = 'foo', 
    b = 42,
    c = {};

let o = { 
  a: a,
  b: b,
  c: c
}

With ECMAScript 2015, there is a shorter notation available to achieve the same:

let a = 'foo', 
    b = 42, 
    c = {};

// Shorthand property names (ES2015)
let o = {a, b, c}

// In other words,
console.log((o.a === {a}.a)) // true

Duplicate property names

When using the same name for your properties, the second property will overwrite the first.

let a = {x: 1, x: 2}
console.log(a) // {x: 2}

In ECMAScript 5 strict mode code, duplicate property names were considered a SyntaxError.  With the introduction of computed property names making duplication possible at runtime, ECMAScript 2015 has removed this restriction.

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;
  }
}

Method definitions

A property of an object can also refer to a function or a getter or setter method.

let o = {
  property: function (parameters) {},
  get property() {},
  set property(value) {}
}

In ECMAScript 2015, a shorthand notation is available, so that the keyword "function" is no longer necessary.

// Shorthand method names (ES2015)
let o = {
  property(parameters) {},
}

In ECMAScript 2015, there is a way to concisely define properties whose values are generator functions:

let o = {
  *generator() {
    ...........
  }
};

Which is equivalent to this ES5-like notation (but note that ECMAScript 5 has no generators):

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

For more information and examples about methods, see method definitions.

Computed property names

Starting with ECMAScript 2015, the object initializer syntax also supports computed property names. That allows you to put an expression in brackets [], that will be computed and used as the property name. This is reminiscent of the bracket notation of the property accessor syntax, which you may have used to read and set properties already.

Now you can use a similar syntax in object literals, too:

// Computed property names (ES2015)
let i = 0
let 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

const items = ["A","B","C"];
const obj = {
[items]: "Hello"
} 
console.log(obj); // A,B,C: "Hello"
console.log(obj["A,B,C"]) // "Hello"



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

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

Spread properties

The Rest/Spread Properties for ECMAScript proposal (stage 4) adds spread properties to object literals. It copies own enumerable properties from a provided object onto a new object.

Shallow-cloning (excluding prototype) or merging objects is now possible using a shorter syntax than Object.assign().

let obj1 = { foo: 'bar', x: 42 }
let obj2 = { foo: 'baz', y: 13 }

let clonedObj = { ...obj1 }
// Object { foo: "bar", x: 42 }

let mergedObj = { ...obj1, ...obj2 }
// Object { foo: "baz", x: 42, y: 13 }

Note that Object.assign() triggers setters, whereas the spread operator doesn't!


Prototype mutation

A property definition of the form __proto__: value or "__proto__": value does not create a property with the name __proto__.  Instead, if the provided value is an object or null, it changes the Web/JavaScript/Reference/Operators/Prototype of the created object to that value.  (If the value is not an object or null, the object is not changed.)

let obj1 = {}
assert(Object.getPrototypeOf(obj1) === Object.prototype)

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

let protoObj = {}
let obj3 = {'__proto__': protoObj}
assert(Object.getPrototypeOf(obj3) === protoObj)

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

Only a single prototype mutation is permitted in an object literal. Multiple prototype mutations are a syntax error.

Property definitions that do not use "colon" notation are not prototype mutations. They are property definitions that behave identically to similar definitions using any other name.

let __proto__ = 'variable'

let obj1 = {__proto__}
assert(Object.getPrototypeOf(obj1) === Object.prototype)
assert(obj1.hasOwnProperty('__proto__'))
assert(obj1.__proto__ === 'variable')

let obj2 = {__proto__() { return 'hello'; }}
assert(obj2.__proto__() === 'hello')

let obj3 = {['__prot' + 'o__']: 17}
assert(obj3.__proto__ === 17)


Specifications

Specification
ECMAScript (ECMA-262)The definition of 'Object Initializer' in that specification.

Browser compatibility

Update compatibility data on GitHub

Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
Object initializer Chrome

Full support 1

Edge

Full support 12

Firefox

Full support 1

IE

Full support 1

Opera

Full support 4

Safari

Full support 1

WebView Android

Full support 1

Chrome Android

Full support 18

Firefox Android

Full support 4

Opera Android

Full support 10.1

Safari iOS

Full support 1

Samsung Internet Android

Full support 1.0

nodejs

Full support 0.1.100

Computed property names Chrome

Full support 47

Edge

Full support 12

Firefox

Full support 34

IE

No support No

Opera

Full support 34

Safari

Full support 8

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android

Full support 34

Opera Android

Full support 34

Safari iOS

Full support 8

Samsung Internet Android

Full support 5.0

nodejs

Full support 4.0.0

Shorthand method names Chrome

Full support 47

Edge

Full support 12

Firefox

Full support 34

IE

No support No

Opera

Full support 34

Safari

Full support 9

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android

Full support 34

Opera Android

Full support 34

Safari iOS

Full support 9

Samsung Internet Android

Full support 5.0

nodejs

Full support 4.0.0

Shorthand property names Chrome

Full support 47

Edge

Full support 12

Firefox

Full support 33

IE

No support No

Opera

Full support 34

Safari

Full support 9

WebView Android

Full support 47

Chrome Android

Full support 47

Firefox Android

Full support 33

Opera Android

Full support 34

Safari iOS

Full support 9

Samsung Internet Android

Full support 5.0

nodejs

Full support 4.0.0

Spread properties

Experimental'

Chrome

Full support 60

Edge

Full support 79

Firefox

Full support 55

IE

No support No

Opera

Full support 47

Safari

Full support 11.1

WebView Android

Full support 60

Chrome Android

Full support 60

Firefox Android

Full support 55

Opera Android

Full support 44

Safari iOS

Full support 11.3

Samsung Internet Android

Full support 8.0

nodejs

Full support 8.3.0

Legend

Full support  
Full support
No support  
No support
Experimental. Expect behavior to change in the future.'
Experimental. Expect behavior to change in the future.


See also