DEV Community

Ian Holden
Ian Holden

Posted on • Edited on • Originally published at ianholden.co.uk

Future JavaScript – Play with JavaScript syntax features today (2/4 – Syntax)

In this post, I am going to show you some of the future JavaScript features that you can use today. Our focus will be on syntactical features that were outlined as less commonly used in 2020's State of JS survey.

This post is the second post in a series focussing on using future JavaScript features. If you would like to know how you can set up a project to use these new features, read the first future JavaScript post in this series.

Please note, if you have not read the first post and would like to try these JavaScript features for yourself, you will need a compiler like Babel. For your convenience, I have embedded a Code Sandbox playground with all examples included at the bottom of this post.

Getting Started

Firstly, we will see how nullish coalescing can help you avoid null or undefined errors in your code at runtime.

Next, we will explore optional chaining. This feature offers similar benefits to nullish coalescing but can be expressed in a slightly different way.

Finally, we will look at private fields in ES6 classes. Private fields allow you to privately scope your variables to a class object (or instance). This aligns JavaScript classes with other object-oriented languages that you may be familiar with (like Java for example).

Let's begin with nullish coalescing.

Nullish Coalescing

Nullish coalescing is a new operator that is formed of two question marks ??.

This operator will return the left-hand side operand if it is not null or undefined. Otherwise, it will return the right-hand side operand.

Primitive data type examples

Remember, the nullish coalescing operator will only return values that are not null or undefined. Therefore, the following examples work like so:

undefined ?? "return me" // "return me"
null ?? "return me" // "return me"
Enter fullscreen mode Exit fullscreen mode

However, what do you think would happen if we try the same examples with booleans? Take a look:

true ?? "do not return me - return true" // true
false ?? "do not return me - return false" // false
Enter fullscreen mode Exit fullscreen mode

Surprised? The last example actually returns a false boolean value, which is quite unusual if you were expecting this operator to work as a standard if ... else conditional would.

If you are looking for an operator that does not return falsey values, you should use the logical OR (||) operator. To compare this with the nullish coalescing example above, see the following:

false ?? "do not return me - return false" // false
false || "return me" // "return me"
Enter fullscreen mode Exit fullscreen mode

This makes the nullish coalescing operator very useful. If you are using numbers that are initialised as 0, or strings that are initialised as '', you may want to return these because they are valid values for your variables. See the example below:

0 ?? "do not return me - return 0" // 0
"" ?? "do not return me - return an empty string" // ""
Enter fullscreen mode Exit fullscreen mode

Object examples

For these next two examples, we will look at how nullish coalescing affects objects. We will work under the assumption that the following object is defined:

const obj = {
  key: "value"
};
Enter fullscreen mode Exit fullscreen mode

We can check the existence of an object's nested property using this technique really easily:

obj.key ?? "do not return me - return value" // "value"
obj.key.nestedKey ?? "return me" // "return me"
Enter fullscreen mode Exit fullscreen mode

In our next feature, we will see how optional chaining can help us work with objects in a similar, but slightly different manner.

Optional Chaining

Optional Chaining allows you to use .? to access nested attributes in an object.

It will allow you to access objects in a familiar way but it will short circuit if it meets a nested attribute that is being accessed from a null or undefined parent.

We will start our examples by defining an object (the same object as before in fact) that we will test this operator on:

const obj = {
  key: "value"
};
Enter fullscreen mode Exit fullscreen mode

Currently, we know that objects in JavaScript work in the following way:

obj.key // "value"
obj.badKey // undefined
Enter fullscreen mode Exit fullscreen mode

However, when we try and go one level deeper for a key that is undefined, we are met with an error:

obj.badKey.key // Uncaught TypeError: Cannot read property 'key' of undefined
Enter fullscreen mode Exit fullscreen mode

This is where the optional chaining operator becomes useful. In some scenarios, we may not want our program to error if we try to access an undefined nested property. We can achieve this in the following way:

obj.badKey?.key // undefined
Enter fullscreen mode Exit fullscreen mode

Private Fields

You can add private properties or methods (fancy names for class variables and class functions) to your classes by using private fields. This ensures that they are privately scoped so that they can only be interacted with by the class.

Private properties/methods can be defined by the # character.

Babel config

Before we can begin using this feature, it is worth noting that currently (as of February 2021 - at the time of writing this post), this feature is still experimental. This means that if we are using Babel to enable this future JavaScript feature, we need to add a little extra config.

First, we need to ensure that we have the relevant Babel plugins installed:

npm install @babel/plugin-proposal-private-methods @babel/preset-env --save-dev
Enter fullscreen mode Exit fullscreen mode

Once these have been installed, we can add them to our .babelrc file. To see an example .babelrc file, you can see how I have used these plugins below:

{
  "presets": [
    "@babel/env"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-private-methods"
  ],
  "parserOpts": {
    "plugins": [
      "dynamicImport"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Once you have completed this step, your IDE should stop complaining when you use this feature.

Examples

For these examples, we are going to assume that we have defined the following class and have an instance of it stored in the test variable:

class Test {
  #privateField = 1;
  publicField = 2;

  sum() {
    return this.#privateField + this.publicField;
  }
}

const test = new Test();
Enter fullscreen mode Exit fullscreen mode

Now to illustrate how private fields work in this example, look at the following code:

test.publicField // 2
test.privateField // undefined
test.sum() // 3
Enter fullscreen mode Exit fullscreen mode

Hopefully, you can see here that we have defined two properties: publicField as 2 and privateField as 1. When we try to access these properties outside of the class, we can see the value of the private property has not been returned.

When we call the class method sum() however, we can see that it returns 3 which proves that the private attribute's value is being used inside the class.

Live example

If you want a more interactive experience of the features in this post, I have created a corresponding Code Sandbox for you to play with. It is a Node sandbox that uses the Console to log the examples given in this post. To view these logs, you may need to run yarn start in the Code Sandbox console.

Up Next

I hope you enjoyed this description of three of the lesser-used features from the State of JS 2020 survey. Luckily, you can find more examples of future JavaScript features in my next post. Spoiler alert - we will be looking at some of the language features next.

Top comments (0)