4 Ground-breaking JavaScript features of the future
Tags: javascript, webdev
Published: 2020-07-02 17:24:28

Ever since the release of  **ECMAScript 6**  (ES6), JavaScript has been enjoying a very lively and vibrant development. Thanks to the now-yearly release cycle of the  [ECMA-262](https://tc39.es/ecma262/)  standard and hard work of all browser vendors, JS rose to become one of the most popular programming languages in the world!

In  [my recent article](https://areknawo.com/ecmascript-2020-biggest-new-features/), I covered all the new features introduced to the latest release of JS specification -  [ES2020](https://www.ecma-international.org/ecma-262/11.0/). While some were quite interesting, none of them were "ground-breaking". But that's understandable given the current, more frequent update cycle of the specification. There's simply less room for special features like ES6 modules or arrow functions to appear every year.

But it doesn't mean that they won't come eventually which brings us to the topic of this article. Here, I'd like to walk you through 4 of what, in my opinion, are potentially  **ground-breaking**  JavaScript features that are currently at different stages of the  [approval process](https://tc39.es/process-document/). Which, granted - means that we might never see them actually being implemented - but it still should make some pretty insightful experience anyway. Let's get into it!

# [Decorators](https://github.com/tc39/proposal-decorators)

Let's start with arguably the most requested and hyped feature that's been making the headlines for a couple of years now -  **decorators**.

You might be already familiar with them - especially if you're a TypeScript user. They're essentially a meta-programming concept meant to allow you to  _"inject"_  custom functionalities into your classes, their individual fields, and methods, effectively making them  **programmable**.

Consider the following example:

```typescript
function sealed(constructor: Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@sealed
class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet() {
    return "Hello, " + this.greeting;
  }
}
```

Now, I decided to play it safe and go with simple  [TypeScript decorators](https://www.typescriptlang.org/docs/handbook/decorators.html)  example - mainly to demonstrate the general concept. Above, we create the  `sealed`  decorator and apply it to the  `Greeter`  class. As you can see, here, the decorator is simply a function that gets access to the constructor of the class it's applied to (aka  **target**). We use this reference with  [`Object.seal()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal)  to make our class effectively not extensible.

To apply the decorator to our class, we write it just above our target - in this case, a class - with the  `@[name]`  syntax (e.g.  `@sealed`).

You can verify that our decorator is working by compiling the above TypeScript code with  `experimentalDecorators`  option enabled, and trying to alter our class' prototype:

```javascript
Greeter.prototype.test = "test";  // ERROR
```

With that said, you should now have a basic understanding of what decorators are about. But there's one more issue I'd like to address - and that's the current state of this feature.

There's a reason I decided to use the TypeScript implementation in the example above. It's been a few years since the decorator proposal originally appeared, and it's still "only" at  **stage 2**  of 4 stage approval process. There are changes actively being made both to the syntax as well as the functionalities of the decorators. But this didn't stop the JS community from early-adopting the concept - just look at huge open-source projects such as  **TypeScript**  or  **Angular v2+**.

However, this raises the problem of specification  **incompatibilities**  as time goes on and the proposal evolves. There's been a pretty substantial overhaul of decorators specification since their introduction, and most projects have still not implemented it. The TypeScript example I showcased earlier implements the older version. So does Angular and even Babel (although here the implementation of the newer version is  [in progress](https://github.com/babel/proposals/issues/11)). Overall, the newer version with the decorator keyword and composable syntax, haven't seen any kind of mass-adoption just yet.

To sum it all up, decorators do have the  **potential**  to change the way we write our code and that's already visible through their current early-adoption rate. However, at the current stage, they've only fractured the community and, in my opinion, still aren't ready for prime time. So, unless you're using a framework that relies on decorators (like Angular), I'd say you should hold on a little bit longer before using decorators in your production projects.

# [Realms](https://github.com/tc39/proposal-realms)

Slowing down a little, let's talk about something less complicated than decorators -  **Realms**.

You might have already been in scenarios where you need to run your own or third-party code, but don't want to affect your  **global environment**. Many libraries - especially in the browser - work through the global  `window`  object and thus can overlap when you use too many uncontrolled libraries at the same time, resulting in errors.

Currently, the solution for that in browsers are  **iframes**  and for more specific tasks -  **Web Workers**, while on the Node.js side - the  [`vm`](https://nodejs.org/api/vm.html#vm_vm_executing_javascript)  module or  [child processes](https://nodejs.org/api/child_process.html). And that's where Realms API comes into play.

This proposed API is meant to allow you to create distinct global environments called Realms, with each such environment having its own globals. Take a look:

```javascript
var x = 39;
const realm = new Realm();

realm.globalThis.x; // undefined
realm.globalThis.x = 42; // 42
realm.globalThis.x; // 42

x; // 39
```

In the example, we create a new Realm using the  `Realm`  constructor. From this point on, we've got complete access to our new Realm and its global object through the  `globalThis`  property (introduced in ES2020). You can see that variables are kept separate and distinctive between the main  _"incubator"_  Realm and the one we've created.

Overall, Realms API aims to be a very simple, yet useful feature. It has a very specific set of use-cases - it doesn't provide improved security nor multi-threaded capabilities. But for what it does -  **basic environment sandboxing**  without much overhead - it's a very capable API.

Realms are currently at  **stage 2**, and when they eventually come, you can expect to see them used in heavily global-dependent libraries, online sandbox code editors, and various testing applications.

# [Do expressions](https://github.com/tc39/proposal-do-expressions)

Like most languages, JavaScript syntax incorporates both statements and  **expressions**. The most noticeable difference between these constructs is the fact that expressions can be used as values (thus they can be assigned to variables, passed to function calls, etc.), while statements cannot.

Because of this difference, expressions are often favored as the way for cleaner and more compact syntax. In JS this can be seen by looking at the popularity of  **function expressions**  (including arrow functions) over function statements, various array iteration methods (like  `forEach()`) in comparison to loops and - for more advanced developers -  [ternary operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator)  vs  `if`  statements.

Stage 1  **`do`  expressions**  proposal (not to be confused with  `do...while`  loop, which is an entirely different thing) aims to push the boundaries of JS expressions even further.

```javascript
let x = do {
  if (foo()) {
    f();
  } else if (bar()) {
    g();
  } else {
    h();
  }
};
```

In the example above you see the proposed syntax for the  `do`  expressions. Essentially it's a piece of JS code, wrapped inside  `do {}`, last expression of which is "returned" as the end value of the entire do expression.

Similar if not identical effect can be already achieved using  **Immediately Invoked Function Expressions**  (IIFEs), but it's the compact syntax that's most compelling here. You don't need any  `return`s or the same amount of ugly wrapping code (e.g. (`() => {})()`), while still getting access to all the functionalities. That's why I think when they come out, their impact could be similar to ES6 arrow function. The convenience of expressions and friendly syntax in a single package sounds just so good!

# [Pattern matching](https://github.com/tc39/proposal-pattern-matching)

Last but not least, I'd like to talk about the  **pattern matching**  proposal.

You might be familiar with the JS  `switch`  statement. It's similar to using  `if`/`else`  but is a bit more limiting and certainly more suitable for handling a large number of different  `case`s.

```javascript
switch (value) {
  case 1:
    // ...
    break;
  case 2:
    // ...
    break;
  case 3:
    // ...
    break;
  default:
    // ...
    break;
}
```

Personally, I find switch statement inferior to  `if`/`else`  due to its value-comparison-only limitations (you can  [get around that](https://stackoverflow.com/questions/5464362/javascript-using-a-condition-in-switch-case), but I don't know why you'd even want to) and the  **verbose syntax**  with repetitive  `break`  statements.

Now, you can think of pattern matching as a more feature-rich, expression-based, and potentially much more versatile version of the  `switch`  statement. Instead of simple value comparison, pattern matching allows you to - as the name implies - match values to specific patterns that are heavily  **customizable**. Here's a fragment of the proposed API:

```javascript
const getLength = vector => case (vector) {
  when { x, y, z } -> Math.hypot(x, y, z)
  when { x, y } -> Math.hypot(x, y)
  when [...etc] -> vector.length
}
getLength({x: 1, y: 2, z: 3})
```

The syntax is quite unique (although inspired by languages such as  [Rust](https://doc.rust-lang.org/book/ch18-00-patterns.html)  or  [Scala](https://docs.scala-lang.org/tour/pattern-matching.html#inner-main)), but has some similarities to the  `switch`  statement we already know. Instead of the  `switch`  keyword, we've got  `case`  which marks the match beginning. Then, inside a block, we specify different patterns to check against using the  `when`  keyword followed by a syntax similar to existent  **object destructuring**. We can match against objects containing selected properties, against those properties' values and a lot more. For full details about possible matching capabilities check out the  [proposal explainer document](https://github.com/tc39/proposal-pattern-matching/blob/latest/CORE.md).

After the pattern, you use "flat arrow" (`->`) syntax pointing to an expression (potentially even other values) that should be evaluated when a certain pattern is matched.

From my point of view, having such functionality in JS would enable us to write some truly  **next-level code**. However, I find the currently-proposed syntax a bit too verbose, as it introduces a lot of new constructs that weren't seen in the language before. And the fact that this feature is still at  **stage 1**, leaves me thinking that there's some room for improvement. The feature is very promising, but it's still has a long way to go before it comes to the official specification.

# Bottom line

This wraps up my list. There are a lot more of other ground-breaking feature proposals like an  [external standard library](https://github.com/tc39/proposal-built-in-modules), or  [pipeline operator](https://github.com/tc39/proposal-pipeline-operator), but in this article, I cherry-picked only these few that I found interesting. Keep in mind that these are still only proposals and might change over time, or not actually implemented at all!. But if you want to be an  **early adopter**  anyway, I suggest you take a deeper look at projects like  [Babel](https://babeljs.io/), which bring many of these proposals to live (especially those that are only syntax-related) before they even ship, for you to play with them.

So, that's it! If you've got some personal best  [JS proposals](https://github.com/tc39?q=proposal)  at different stages, or are thinking of features that aren't even among them, be sure to share them  **down in the comment**  section below. And  **follow me**  on  [Twitter](https://twitter.com/areknawo),  [Facebook](https://facebook.com/areknawoblog), or through  [my weekly newsletter](https://areknawo.com#newsletter)  for more web development content. Thanks for reading and happy coding!