Enhanced Object Literal Value Shorthand: JavaScript ES6 Feature Series (Pt 6)

Paige Niedringhaus
ITNEXT
Published in
8 min readSep 29, 2019

--

Because typing the same thing twice in an object is crazy

Photo by Kevin Ku on Unsplash

Introduction

The inspiration behind these posts is simple: there are still plenty of developers for whom, JavaScript doesn’t make a whole lot of sense — or at the very least, is perplexing at times.

According to Wikipedia, JavaScript powers just under 95% of the 10 million most popular web pages, as of May 2017.

Since JS powers so much of the web, I wanted to provide a slew of articles and examples of ES6+ features that I use regularly, for other developers to reference.

The aim is for these articles to be short, in-depth explanations about various improvements to the language, that I hope will inspire you to write some really cool stuff using JS. Who knows, you might even learn something new along the way. 😄

My sixth post in this series will be about the new object property and method value shorthands introduced by ES2015, the most concise ways yet to initialize object properties from variables and define functions.

Objects: Everything in JavaScript is one

When it comes to JavaScript, you may have heard the phrase thrown around that “everything in JavaScript is an object.” Functions, strings, arrays, objects — they’re all objects. It can also be something else, but except for primitives, everything else is also an object in JS.

This article, however, concerns itself with object objects; the ones commonly initialized using the new Object(), Object.create() or literal notation initializers.

Let’s look at them before we get to the new changes courtesy of ES2015.

Object initializer examples: new Object()

// object initialization options// object constructor
function Pet(type, name, age, greeting) {
this.breed = type;
this.name = name;
this.age = age;
this.greeting = greeting;
this.sayHello = function () {
return `${this.name} says 'hello' as ${this.greeting}`;
}
}
// new Object()
const pet1 = new Pet("cat", "Felina", 3, "meow");
console.log(pet1);
/* prints: Pet {
breed: 'cat',
name: 'Felina',
age: 3,
greeting: 'meow',
sayHello: [Function] } */
console.log(pet1.sayHello());
// prints: Felina says 'hello' as meow

This first example shows how to create an object using the new Object() keywords. First, an object constructor called Pet is defined, which takes in a number of parameters, and even has its own method, sayHello() attached to it.

Then, the variable pet1 is declared and new Pet() is called with the appropriate parameters passed to it. Voilà — a new object named pet1 now exists when you call it or its method, pet1.sayHello().

Object initializer examples: Object.create()

// Object.create()
const pet2 = Object.create(pet1);
pet2.breed = "dog";
pet2.name = "Rufus";
pet2.age = 4;
pet2.greeting = "woof";
console.log(pet2);
/* prints: Pet {
breed: 'dog',
name: 'Rufus',
age: 4,
greeting: 'woof' } */
console.log(pet2.sayHello());
// prints: Rufus says 'hello' as woof

The second example above demonstrates using the Object.create() initializer. This option requires an already existing object exist as the prototype for the newly created object.

In this instance, pet2 takes pet1 from the first example as its prototype. Then, pet2 assigns all the properties from pet1 with new values, and it also inherits the method sayHello() from pet1 as well.

So when pet2.sayHello() is called, it prints out "Rufus says 'hello' as woof". Simple as that.

Object initializer examples: object literals {}

// object literal initialization
const pet3 = {
type: "guinea pig",
name: "Holly",
age: 6,
greeting: "snuffle",
sayHello: function() {
return `${this.name} says 'hello' as ${this.greeting}`
}
}
console.log(pet3);
/* prints: { type: 'guinea pig',
name: 'Holly',
age: 6,
greeting: 'snuffle',
sayHello: [Function] } */
console.log(pet3.sayHello());
// prints: Holly says 'hello' as snuffle
// object literal property and method assignment by variables
const type = "fish";
const name = "Nemo";
const age = 2;
const greeting = "bloop";
function sayHello() {
return `${this.name} says 'hello' as ${this.greeting}`;
}
const pet4 = {
type: type,
name: name,
age: age,
greeting: greeting,
sayHello: sayHello
}
console.log(pet4);
/* prints: { type: 'fish',
name: 'Nemo',
age: 2,
greeting: 'bloop',
sayHello: [Function: sayHello] } */
console.log(pet4.sayHello());
// prints: Nemo says 'hello' as bloop

This final object initialization is the most frequently used one in day-to-day coding, by far: object literal initialization.

It can be done two ways:

  1. By declaring the object and assigning all its properties and methods at the same time its initialized: like pet3.
  2. By declaring any variables and functions ahead of time, then assigning those to a new object, like pet4.

However you choose to do it, both ways are perfectly acceptable, and frequently used.

Object literals, in particular, are what ECMAScript 2015 improves dramatically upon, let’s see how.

Shorthand Property Names

The first thing ES2015 improved upon regarding object literals is the abbreviated initialization of a property within an object, provided that the property key matches an existing variable name. This is known by most as: shorthand property names.

Traditional syntax for assigning variables to an object’s properties

// traditional object property assignment
const breed = "chinchilla";
const howOld = 1;
const nickname = "Chi Chi";
const activities = "dust baths";
function funFact() {
return `${this.nickname}'s fun fact is she likes ${this.activities}`;
}
const exoticPet = {
breed: breed,
nickname: nickname,
howOld: howOld,
activities: activities,
funFact: funFact
};
console.log(exoticPet);
/* { breed: 'chinchilla',
nickname: 'Chi Chi',
howOld: 1,
activities: 'dust baths',
funFact: [Function: funFact] } */
console.log(exoticPet.funFact());
// prints: Chi Chi's fun fact is she likes dust baths

Above is the traditional way to assign variables to an object’s properties. Seems a lot of extra typing in creating exoticPet when the properties already match the variable names doesn’t it?

Let’s fix that redundancy in the next example.

ES2015 shorthand example of assigning like-named variables to an object’s properties

// es2015 shorthand object property assignment
const otherBreed = "alpaca";
const firstName = "Alfie";
const likes = "frolicking";
function timeSpent() {
return `${this.firstName} enjoys ${this.likes} whenever he can.`;
}
const exoticPet2 = {
otherBreed,
firstName,
likes,
timeSpent
};
console.log(exoticPet2);
/* { otherBreed: 'alpaca',
firstName: 'Alfie',
likes: 'frolicking',
timeSpent: [Function: timeSpent] } */
console.log(exoticPet2.timeSpent());
// prints: Alfie enjoys frolicking whenever he can.

As you can see, the syntax for exoticPet2 is much cleaner than the previous example. Since exoticPet2’s property names match the variables declared above: otherBreed, firstName, and so on, you can simply declare the property names once and ES2015 understands how to insert the variables of the same name into the object.

Pretty neat trick, huh? I do so appreciate this particular nicety of the ES6 improvements. I use it frequently.

Note: Beware of using the same name for your properties, the second property will overwrite the first.

Beware: Duplicate properties assume the last value assignment

// duplicate properties assume the last value assignedconst exoticPet3 = { type: "parrot", type: "cockatoo"};
console.log(exoticPet3.type); // prints: cockatoo

Shorthand Method Definitions

Next up in our improvements to object literals courtesy of ES2015: method shorthand definitions. Method definition shorthand syntax omits the function keyword and colon, just like with the property assignments.

Traditional syntax to create methods (functions) in an object

// traditional method definitions
const person = {
play: function() {
return "I like to play board games with my friends.";
},
swim: function() {
return "When I exercise, I like to swim laps in the pool.";
}
};
console.log(person.play()); // prints: I like to play board games with my friends.console.log(person.swim()); // prints: When I exercise, I like to swim laps in the pool.

In traditional JavaScript, methods (functions attached to objects), similar to normal object properties, are declared on an object with a property name like play or swim, and then assigned values with the traditional anonymous function declaration syntax of function() { /* ...do something here */ };.

Then, the object’s method can be called just like its properties are: person.play() or person.swim(). Nothing too earth shattering there.

But does anyone really like anonymous functions much? Nah. It doesn’t seem to add much except unnecessary code, and if we have concise arrow function expressions now for traditional functions, why not make something similar for object methods too?

ES2015 shorthand to create methods (functions) in an object

// es2015 shorthand method definitions
const person2 = {
play() {
return "I like to play the violin in my free time.";
},
swim() {
return "Swimming in the ocean is my favorite thing to do at the beach.";
}
};
console.log(person2.play()); // prints: I like to play the violin in my free time.console.log(person2.swim()); // prints: Swimming in the ocean is my favorite thing to do at the beach

Introducing ES2015 method shorthands for object literal notation. The person2 object has two methods similar to person1, play() and swim(), and as you also see, the declarations on the the object itself lack the function keyword, instead taking the property name and making that the function name instead.

Cleaner, more succinct, and to be honest, it makes more sense to me when I read the code written this way than with the anonymous functions of old.

Ok, time to move to the last ES2015 object literal improvement: computed property names.

Computed Property Names

Starting with ECMAScript 2015, the object initializer syntax supports computed property names. This feature allows you to put an expression in brackets [], that will be computed and used as the property name.

ES2015 shorthand for computing property keys / names via bracket notation

// computed property names / keys
let i = 1;
const items = {
['item' + i++] : i,
['otherItem' + i++] : i,
['aThirdItem' + i++] : i
}
console.log(items); // prints: { item1: 2, otherItem2: 3, aThirdItem3: 4 }

To be honest, I haven’t used this computed property names functionality once in daily life, but it’s nice to know it’s there if the situation should call for it, right?

And that’s it. That’s what you need to know about object literals in JavaScript as of ES2015.

Conclusion

All JS developers have gotten familiar with the language’s many quirks and gotchas over time, but lately, each year the ECMAScript committee releases new updates to the JavaScript language designed to make our lives easier. Some updated syntax changes look more foreign that others, but I’m happy to say the improvements to how we work with object literals are more similar to the older syntax than most.

Happily, the changes result in concise objects that can be more easily assigned variables, methods and even new, computed property names. It’s pretty great.

My aim with this blog series is to dive into some of my favorite parts of the JavaScript and ES6 syntax in use today, and show you how to use the best bits to maximum effect.

Check back in a few weeks, I’ll be writing about more JavaScript and ES6 or something else related to web development.

Thanks for reading, I hope you’re able to use this new object literal shorthand to make your own JavaScript objects more compact and manageable in the future.

If you enjoyed reading this, you may also enjoy some of my other blogs:

--

--

Staff Software Engineer at Blues, previously a digital marketer. Technical writer & speaker. Co-host of Front-end Fire & LogRocket podcasts