JavaScript Object Literal Shorthand Syntax Basics

JavaScript

JavaScript object literal shorthand syntaxJavaScript Object Literal Shorthand Syntax is a feature that provides a path to cleanerJavaScript. Not only does it provide a way to reduce the size of your code, but it will be easier to read and understand.

Many ECMAScript 2015 features provide improved ways to solve problems. Object literal shorthand syntax is a bit unique in that it’s not so much a shiny new tool, but an improved syntax. Now it might be tempting to dismiss this kind of feature as less-than-stellar, but it’s worth working into your routine for a number of reasons. For example, an improved syntax can lead to less code, and not only that, the code you write can be easier to understand. And believe me, those who inherit your code will thank you for this. So, in this article, I’ll explain how to use object literal shorthand syntax when defining properties and methods.

Typical Object Literal Syntax – Example # 1

See the Pen JavaScript Object Literal Shorthand Syntax – Challenge by Kevin Chisholm (@kevinchisholm) on CodePen.

Let’s start with the way we’re used to working with object literals. In Example # 1 we have a getGoods() method that returns an object. The value argument is used on execution to set the value property, and the lowerValue() and raiseValue() methods lower and raise that value property. So this is all fine and everything works exactly as expected. In fact, if you look at the UI, the text that you see shows that our methods set and value property accordingly. Unlike many of the examples in this blog, there is nothing to “fix” here. Our code works fine and follows a typical syntax pattern because, as stated, I mainly wanted to establish that this is the way we normally work with object literals.

Object Literal Shorthand Syntax -Example # 2

See the Pen JavaScript Object Literal Shorthand Syntax – Solution by Kevin Chisholm (@kevinchisholm) on CodePen.

Now, in Example # 2 we do things quite differently. To start, look at Line # 3. When we set the value property, there is no colon; we simply assign the value of the “value” argument that was provided when the function was executed. This syntax is concise, thereby requiring you to write less code. Now it may seem like a very small savings here, but when you have an application with many thousands of lines of code, the savings quickly add up.

Okay, so next, look at where we define the lowerValue() and raiseValue() methods. Here, notice two things are missing: there is no colon, and we don’t need the function keyword. We simply provide the parentheses and the curly braces (as well as the code inside the curly braces). Here, too, the savings may seem small on a per-line basis, but in a large application, the difference will be dramatic. And the additional benefit, especially when defining methods, is that the code is a bit easier to read.

Understanding Context in JavaScript – Object Literals

JavaScript

JavaScript Logo - context

Why is the word “this” so important in JavaScript?

In the post: “Understanding Scope in JavaScript,” I covered the basics of how scope works when dealing with functions. Sometimes the words “scope” and “context” are used interchangeably, which only leads to confusion because they are not the same thing.

In JavaScript, “context” refers to an object. Within an object, the keyword “this” refers to that object (i.e. “self”), and provides an interface to the properties and methods that are members of that object. When a function is executed, the keyword “this” refers to the object that the function is executed in.

Here are a few scenarios:

So, as you can see, “this” can easily give you a headache. But hang in there; we are getting to the good stuff now.

In a nutshell, in Object-literals, you don’t have local variables; you have properties of the object. So, where inside of the function foo() I might say “var drink = ‘beer’; “, for an object literal called “bar”, I would say “bar.dink = ‘beer’. “ The difference is that “beer” is a property of “bar”, whereas when a function is executing, a local variable is defined by the “var” keyword and cannot be seen by anyone or anything outside of the function.

Example # 1

Here is the jsFiddle.net link for Example # 1: http://jsfiddle.net/Q9RJv/

In Example # 1, we first create a global variable named “drink”, and set it equal to “wine”. We’ll come back to that in a minute.

Next, we create an Object Literal named “foo”, with a property “drink” that is equal to “beer”. There is also a method that simply returns “drink”. But why does it return “wine”, and not “beer”? This is because in the object “foo”, “drink” is a property of foo, not a variable. Inside of functions, when reference is made to a variable, the JavaScript engine searches the scope chain and returns the first match it finds.

Although this function executes in the context of “foo”, “foo” does not have a variable named “drink”. It has a property named “drink”, but not a variable. So the JavaScript engine searches the next level of the scope chain. The next level of the scope chain is the global object, which contains a variable named “drink”, so the value of that variable (“wine”), is returned.

But wait a minute Kevin, how can we make reference to the property “drink” that is in the context of the object “foo”?

I’m glad you asked.

Example # 2

Here is the jsFiddle.net link for Example # 2: http://jsfiddle.net/HGM93/

In Example # 2, the only change we have made is that in the anonymous function that is assigned to “getDrink”, we return “this.drink” instead of “drink

This is an important detail. When a function executes in the context of an object , the keyword “this” refers to that object. You can access any of the properties of the object by using the “this” keyword, add new ones (e.g. this.color = “blue”), and change existing ones (e.g. this.drink = “juice).

Using Dot Notation to Create a JavaScript Object Literal

Example # 3

Here is the jsFiddle.net link for Example # 3: http://jsfiddle.net/ZA77k/

In Example # 3, we have the exact same functionality as Example # 2. From the JavaScript engine’s perspective, we have achieved the same goal, and the console output is exactly the same.

The difference is how we organized our code. In Example # 2, we created the properties “drink” and “getDrink” at the exact same time that we created the object literal “foo”. It is all one expression. In Example # 3, we create an empty object named “foo” first, and then use dot notation to add properties to the object one-by-one. I just wanted to point out that there is more than one way to go about all of this from a syntax perspective.

Object Literals Can Contain Other Object Literals, and those Objects Have Their Own Context

Example # 4

Here is the jsFiddle.net link for Example # 4: http://jsfiddle.net/8p38y/

In Example # 4, we have added a new property to “foo”, and that property is yet another object. At first it is empty (i.e. foo.under21 = {}), and then we add two properties to it. The first property is “drink”, which is set equal to “soda”. Don’t’ confuse this with the property “drink” that is set in the context of “foo” which is equal to “beer”. In the context of “foo.under21”, “drink” is equal to “soda”.

The second property of “foo.under21” has an anonymous function assigned to it. That anonymous function returns “this.drink”. In the context of “foo.under21”, “drink” is equal to “soda”, so calling that function returns “soda”.

So the point of this example is that object literals can have properties that are themselves objects, and those objects have their own context. When functions execute in the context of those objects “this” refers to the object, and so on. I am aware of no limit to this kind of object nesting.

The JavaScript .call() and .apply() Methods Allow You to Dynamically Change the Context In Which a Function is Executed

Example # 5

Here is the jsFiddle.net link for Example # 5: http://jsfiddle.net/A5ydt/

Ok, so here is the bonus question: In Example # 5, why does a call to “foo.under21.getDrink()” now return “wine” ?

This is because we changed the inner-workings of that function. Instead of simply returning “this.drink”, we use the JavaScript “.call()” method, which allows you to execute any function in the context of another object. When you do not specify the context in which that function is to be “called”, it executes in the context of the global object. In the global context, there is a variable named “drink” and it is equal to “wine”, so “wine” is returned.

Example # 6:

Here is the jsFiddle.net link for Example # 6: http://jsfiddle.net/cS4cv/

In Example # 6, “soda” is returned because when we used the JavaScript “.call()” method, we specified the context in which the function is to execute. In this case, the context we specify is “this”. “this” refers to the context of “foo.under21”, and “foo.under21” has a property named “drink”, so the value “soda” is returned.

Summary

The last two examples may seem like overkill, but I wanted to point out that just when you start to get a handle on the concept of context in JavaScript object literals, you must realize that there is a bit more to consider. JavaScript Object Literals can have properties that are also objects, and those objects have their own context.

In each case, when a function executes within that context, inside of the function, the “this” keyword refers to the object that the function is a property of, because the function executes in the context of that object. By using the JavaScript “.call()” method (or “.apply()” method), you can programmatically change the context in which that function executes, which changes the meaning of the “this” accordingly.