5 Most Wanted Features in JavaScript

November 13, 2017

JavaScript is a language we all know, love and love to hate. It’s been an incredibly versatile tool and an easy-to-learn language, which made it the choice of many developers for developing great applications on the front-end and lately on the back-end too. We’ll take a look at some features that would (and possibly will) make it more of a breeze to use.

Prologue

Any application that can be written in JavaScript, will eventually be written in JavaScript

  • Jeff Atwood

I’ve been working for JavaScript on different levels for almost 10 years. Those developers who were around since at least 2015 will know that the language took a huge turn in development since then. There is now a scheduled release of the commitee responsible for the development of this language called EcmaScript (the canonical name for the language most of us call JavaScript). The board responsible for developing the language is TC-39. Quick advancements in syntax and a stable yearly release schedule drove many pioneers of the language to push for new features, including syntactical sugar and new APIs.

Let’s take a look at a few proposals and also some features I think would have a place in the language.

1. Pipeline Operator

This one is a proposal for the next release of ESNext. You can read the full proposal here. The case for this, fairly simplistic syntactic sugar is the fact that functional programming is on the incline in terms of popularity. This operator would make it easier to chain functions, via a special syntax. Here’s how it works:

function reverse(str) {
  return str
    .split("")
    .reverse()
    .join("");
}

let example = "Hello, World!";

Given those functions and the value we can do:

console.log(reverse(example)); // <- !dlroW ,olleH"

console.log(example |> reverse); // <- !dlroW ,olleH"

That weird |> operator calls the first part of the statement as the second part’s argument. Neat in itself, but even better with chaining:

function lowercase(str) {
  return str.toLowerCase();
}

function replaceWith(toReplace, replacement) {
  return function replace(str) {
    return str.replace(toReplace, replacement);
  };
}

let res = example |> reverse |> lowercase |> replaceWith("!", "?!");

console.log(res); // <- ?!dlrow ,olleh"

I think that’s very nice syntax, but what it also allows you to do is use Angular-like pipes in libraries, like React, like so:

function date(d) {
  return d.toLocaleDateString();
}

const Comp = ({ createdAt }) => <div>{createdAt |> date}</div>;

2. Bind Operator

This one is another proposal in stage 0. You can read more about it here. The idea is that sometimes you need to do ugly stuff like:

getUsers().then(users => console.log(users));

// or

getUsers().then(console.log.bind(console));

This operator introduces new syntax, so you can do:

getUsers().then(::console.log);

One of the examples on the proposal page outlines this one nicely:

// Create bindings for just the methods that we need
let { find, html } = jake;

// Find all the divs with class="myClass", then get all of the "p"s and
// replace their content.
document
  .querySelectorAll("div.myClass")
  ::find("p")
  ::html("hahaha");

I think it’s a nice syntactic sugar and the future extensions section also mentions possibility of constructor binding, like this:

class Animal {
    constructor(name) {
        this.name = name
    }
}

const animals = ['dog', 'cat', 'penguin'].map(Animal::new)

console.log(animals)
/*
<- (3) [
    Animal: { name: 'dog' },
    Animal: { name: 'cat' },
    Animal: { name: 'penguin' }
]
*/

3. Static Method Invokator

This is one I came up with in my free-time. I am sure someone’s thought of this feature before, so I’m not claiming ownership, but basically this is the use case:

const myObj = {
  name: "myObj",
  type: "example",
  someProperty: "someValue"
};

Object.values(myObj).forEach(console.log);

Accessing static properties could be better, for example:

myObj->values().forEach(console.log)

This could be super useful for stuff like:

[1,2,3]->isArray() // true

Of course in that particular case it would fail if it wasn’t an array in the first place, due to it not having the method isArray(), which leads me to the next one…

4. Optional Chanining

This feature is used in trendy languages like Swift and is also a stage 1 proposal for JavaScript, which you can read here.

The use case is that in languages like JavaScript, where the exact shapes of objects (and everything is an object here) may not be known and can change at run-time unexpectedly, like in the case of user input.

Let’s see an example where you try to select a DOM Node which may not exist:

let foo = document.querySelector("[data-foo=true]")?.value;

This replaces the need for doing things like:

let foo =
  document.querySelector("[data-foo=true]") &&
  document.querySelector("[data-foo=true]").value;

Which is not very expressive and breaks the flow of the code.

5. Method Cascading

This exists in Dart and is particularly useful for handling cases where you do not care about the return value of a method, but you want to keep operating on the same class.

So instead of doing:

const node = document.querySelector("#node");

node.classList.add("some-class");
node.classList.remove("other-class");

You could do:

node.classList.add('some-class')
    ..remove('other-class')

The syntactic sugar is a double-dot notation that tells the engine that the class on which the previous method invokation took place (in the example node.classList) should also be the class on which the next method is called. You could chain this indefinitely.

Another interesting idea is nullable cascading, which ties in with the previous idea:

myClass.method1()
    ..method2()
    ..anotherMethod('param')
    ?..mayHaveThisMethod(true, 'or not')

This would not throw an error if the last method didn’t exist.

Conclusion

This is my list of features that may see light in future EcmaScript releases, or ones I find interesting and would love to use natively in the browser or in Node JS at some point.

Thank you for the read. If you have your own list, say hi to me on my social media and let’s chat! 😁