Object Literal Syntax Extensions
The object literal is one of the most popular patterns in JavaScript. JSON is built upon its syntax, and it’s in nearly every JavaScript file on the Internet. The object literal is so popular because it’s a succinct syntax for creating objects that otherwise would take several lines of code. Luckily for developers, ECMAScript 6 makes object literals more powerful and even more succinct by extending the syntax in several ways.
Property Initializer Shorthand
In ECMAScript 5 and earlier, object literals were simply collections of name-value pairs. That meant there could be some duplication when property values are initialized. For example:
function createPerson(name, age) {
return {
name: name,
age: age
};
}
The createPerson()
function creates an object whose property names are the same as the function parameter names. The result appears to be duplication of name
and age
even though one is the name of an object property while the other provides the value for that property. The key name
in the returned object is assigned the value contained in the variable name
, and the key age
in the returned object is assigned the value contained in the variable age
.
In ECMAScript 6, you can eliminate the duplication that exists around property names and local variables by using the property initializer shorthand. When an object property name is the same as the local variable name, you can simply include the name without a colon and value. For example, createPerson()
can be rewritten for ECMAScript 6 as follows:
function createPerson(name, age) {
return {
name,
age
};
}
When a property in an object literal only has a name, the JavaScript engine looks into the surrounding scope for a variable of the same name. If it finds one, that variable’s value is assigned to the same name on the object literal. In this example, the object literal property name
is assigned the value of the local variable name
.
This extension makes object literal initialization even more succinct and helps to eliminate naming errors. Assigning a property with the same name as a local variable is a very common pattern in JavaScript, making this extension a welcome addition.
Concise Methods
ECMAScript 6 also improves the syntax for assigning methods to object literals. In ECMAScript 5 and earlier, you must specify a name and then the full function definition to add a method to an object, as follows:
var person = {
name: "Nicholas",
sayName: function() {
console.log(this.name);
}
};
In ECMAScript 6, the syntax is made more concise by eliminating the colon and the function
keyword. That means you can rewrite the previous example like this:
var person = {
name: "Nicholas",
sayName() {
console.log(this.name);
}
};
This shorthand syntax, also called concise method syntax, creates a method on the person
object just as the previous example did. The sayName()
property is assigned an anonymous function and has all the same characteristics as the ECMAScript 5 sayName()
function. The one difference is that concise methods may use super
(discussed later in the “Easy Prototype Access with Super References” section), while the nonconcise methods may not.
I> The name
property of a method created using concise method shorthand is the name used before the parentheses. In the last example, the name
property for person.sayName()
is "sayName"
.
Computed Property Names
ECMAScript 5 and earlier could compute property names on object instances when those properties were set with square brackets instead of dot notation. The square brackets allow you to specify property names using variables and string literals that may contain characters that would cause a syntax error if used in an identifier. Here’s an example:
var person = {},
lastName = "last name";
person["first name"] = "Nicholas";
person[lastName] = "Zakas";
console.log(person["first name"]); // "Nicholas"
console.log(person[lastName]); // "Zakas"
Since lastName
is assigned a value of "last name"
, both property names in this example use a space, making it impossible to reference them using dot notation. However, bracket notation allows any string value to be used as a property name, so assigning "first name"
to "Nicholas"
and “last name"
to "Zakas"
works.
Additionally, you can use string literals directly as property names in object literals, like this:
var person = {
"first name": "Nicholas"
};
console.log(person["first name"]); // "Nicholas"
This pattern works for property names that are known ahead of time and can be represented with a string literal. If, however, the property name "first name"
were contained in a variable (as in the previous example) or had to be calculated, then there would be no way to define that property using an object literal in ECMAScript 5.
In ECMAScript 6, computed property names are part of the object literal syntax, and they use the same square bracket notation that has been used to reference computed property names in object instances. For example:
var lastName = "last name";
var person = {
"first name": "Nicholas",
[lastName]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person[lastName]); // "Zakas"
The square brackets inside the object literal indicate that the property name is computed, so its contents are evaluated as a string. That means you can also include expressions such as:
var suffix = " name";
var person = {
["first" + suffix]: "Nicholas",
["last" + suffix]: "Zakas"
};
console.log(person["first name"]); // "Nicholas"
console.log(person["last name"]); // "Zakas"
These properties evaluate to "first name"
and "last name"
, and those strings can be used to reference the properties later. Anything you would put inside square brackets while using bracket notation on object instances will also work for computed property names inside object literals.