Future JavaScript – Play with JavaScript syntax features today (2/4 – Syntax)
Tags: javascript, tutorial, webdev
Published: 2021-02-07 00:51:09

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](https://2020.stateofjs.com/en-US/features/syntax/) 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](https://dev.to/ianholden/future-javascript-stay-ahead-of-the-curve-by-using-new-javascript-features-today-1-4-intro-3b78) 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:

```javascript
undefined ?? "return me" // "return me"
null ?? "return me" // "return me"
```

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

```javascript
true ?? "do not return me - return true" // true
false ?? "do not return me - return false" // false
```

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:

```javascript
false ?? "do not return me - return false" // false
false || "return me" // "return me"
```

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:

```javascript
0 ?? "do not return me - return 0" // 0
"" ?? "do not return me - return an empty string" // ""
```

### 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:

```javascript
const obj = {
  key: "value"
};
```

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

```javascript
obj.key ?? "do not return me - return value" // "value"
obj.key.nestedKey ?? "return me" // "return me"
```

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:

```javascript
const obj = {
  key: "value"
};
```

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

```javascript
obj.key // "value"
obj.badKey // undefined
```

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

```javascript
obj.badKey.key // Uncaught TypeError: Cannot read property 'key' of undefined
```

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:

```javascript
obj.badKey?.key // undefined
```


## 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:

```bash
npm install @babel/plugin-proposal-private-methods @babel/preset-env --save-dev
```

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:

```json
{
  "presets": [
    "@babel/env"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-private-methods"
  ],
  "parserOpts": {
    "plugins": [
      "dynamicImport"
    ]
  }
}
```

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:

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

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

const test = new Test();
```

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

```javascript
test.publicField // 2
test.privateField // undefined
test.sum() // 3
```

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.

{% codesandbox future-javascript-2020-syntax-xlq0m %}

## 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](https://dev.to/ianholden/future-javascript-use-new-language-features-today-3-4-language-3p42). Spoiler alert - we will be looking at some of the language features next.