DEV Community

Ian Holden
Ian Holden

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

Future JavaScript – Use new Language features today (3/4 - Language)

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 language features that were outlined as less commonly used in 2020’s State of JS survey.

This post is the third in a series focussing on using future JavaScript features. If you would like to know more about using new syntax features or what tools you will need to begin using future JavaScript features, I would recommend viewing the previous posts in this series.

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

Getting Started

Firstly, we will explore how we can use proxies in JavaScript to intercept and change the functionality of a predefined object.

Secondly, we are going to look at decorators and how they can be used to add additional functionality to class methods and attributes.

Last but not least, we will explore the allSettled method of Promises. This will allow us to continue execution of code once we have received a response from every member of an array of Promises.

Let’s begin with proxies.

Proxies

The Proxy feature allows you to change the functionality of an existing object by defining new behaviour. It requires two parameters, target and handler.

  • The target parameter should contain the object that we wish to proxy.
  • The handler parameter should contain a function that tells our system how we should handle the target object. You can use the following handler functions to modify the target.

Let’s start with a code example:

const target = {
  message1: "hello",
  message2: "everyone"
};

const handler = {
  get: function (target, prop, receiver) {
    if (prop === "message2") {
      return "world";
    }
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message1) // undefined
console.log(proxy.message2) // "world"
Enter fullscreen mode Exit fullscreen mode

This code defines a proxy variable and hands it the target object and the handler object as its parameters. The handler object has one property get which looks for a prop named ‘message2’ and if found, returns “world”.

You may have noticed that when we accessed the ‘message1’ attribute, we are returned undefined. This is because we have only told the get function to return something if the ‘message2’ prop is accessed.

We can return all other properties unchanged by using the global Reflect object. Examine the amended example below:

const target = {
  message1: "hello",
  message2: "everyone"
};

const handler = {
  get: function (target, prop, receiver) {
    if (prop === "message2") {
      return "world";
    }
    return Reflect.get(...arguments); // <-- This is our addition
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.message1) // "hello"
console.log(proxy.message2) // "world"
Enter fullscreen mode Exit fullscreen mode

We can now see that our proxy object returns the original value in the message1 attribute.

This is proxies in a nutshell. There are many more features available to us and I would recommend viewing the official documentation on MDN for more advanced examples.

Decorators

Decorators are a JavaScript feature that allows you to decorate existing class functionality by adding additional functionality to it. We can identify decorators by using the @ prefix before a class or its methods.

Babel config

Currently (as of February 2021 – at the time of writing this post), I needed to install a couple of plugins for Babel and update its config to use this feature.

Let’s start by installing the required plugins:

npm install @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties --save-dev
Enter fullscreen mode Exit fullscreen mode

Next, we can update our .babelrc config file to include these new plugins. Here is what mine looks like:

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

Once these plugins are installed, you should see error messages in your IDE disappear when using this feature.

An example

Take a look at the following example for a demonstration of how we can add some simple, additional functionality to a class.

function setSomeProperty(target) {
  target.prototype.someProperty = "I am set by the decorator.";
}

@setSomeProperty
class MyClass {}

const test = new MyClass();

console.log(test.someProperty) // "I am set by the decorator"
Enter fullscreen mode Exit fullscreen mode

In this example, we have a simple function that accepts a target object and adds a property to it. We have also defined a JavaScript class without any methods or properties. This class has a decorator before its definition which references our function.

We can see that when we log someProperty on our test class, we have been returned the value that we set in our function.

Promise.allSettled

With allSettled, we can ensure that we continue code execution when all our asynchronous functions have completed or failed.

Here is how it can be used:

const promise1 = Promise.resolve("FOO");
const promise2 = Promise.reject("BAR");
const promises = [promise1, promise2];

Promise.allSettled(promises).then((results) => {
  console.log(results[0]) // { status: 'fulfilled', value: 'FOO' }
  console.log(results[1]) // { status: 'rejected', reason: 'BAR' }
})
Enter fullscreen mode Exit fullscreen mode

Our example above shows the returned response from the allSettled function. This function really comes into its own when you have a more realistic asynchronous operation which returns a response at different times.

If you would like to know more about Promises, I would recommend this detailed article by Jake Archibald.

Live Example

If you would like to play with these features in a live environment, I have created a Code Sandbox for you to clone and tamper with at your leisure. It is a Node sandbox that uses the Console to log the output from all of the examples that you have seen in this post. To view these logs, you may need to run yarn start in the Console.

Up Next

Thank you for reading my post. If you have enjoyed it, stay tuned as there will be one final instalment in this series next week. Data structures are the topic of next weeks tutorial. I look forward to seeing you then.

Top comments (0)