DEV Community

Jake Dohm
Jake Dohm

Posted on

5 Helpful Language Features Proposed for JavaScript (2018 edition)

Proposals

The features that I mention in this article have been proposed to TC39, the committee that moves JavaScript forward, but are not yet part of the standard that JavaScript conforms to.

There are 5 stages that a proposal goes through to land in JavaScript: Strawman, Proposal, Draft, Candidate, and Finished.

All of the following features are stage 1 proposals, which means they have met the guidelines for what a proposal must be, and have been presented to TC39. If you're interested in learning more about proposals and the process, head over to the official TC39 proposals repo.

Now, to the proposals!

Last Item

lastItem is proposed to be added to the array prototype, which would make it super easy to grab the last item in an array. I love this feature, because I think it's a step in the right direction to solve some common ergonomics issues in JavaScript.

const food = ['🌮', '🥑', '🥓'];

/* New syntax */
const bacon = food.lastItem; // 🥓

/* Old syntax */
const bacon = food[food.length - 1];

Optional Chaining

Optional Chaining is a proposal that streamlines the access of properties on potentially null or undefined types.

The reason we need this is because if object.thing isn't defined, and you write object.thing.test, JS won't just return null or undefined, it will actually throw an error: 🚩"Cannot read property 'test' of undefined".

const inputElement = document.querySelector('input[name=email]');

/* New Syntax */
const street = user.address?.street; // returns street value, or null
const inputValue = inputElement?.value; // returns input value, or null

/* Old Syntax */
const street = user.address && user.address.street;
const inputValue = inputElement ? inputElement.value : undefined;

How it works: If the item before the ? is null OR undefined, it will return null without processing the next item, otherwise it processes the next bit of the "chain". So in the example above, if the object user doesn't have a key of address, then it will return null. If it does, it will process the .street part, and return the value of user.address.street.

I was not a fan when I first saw this proposal, but I've come around on it. The syntax is a bit funky, but it will definitely simplify your codebase.

Null(ish) Coalescing Operator

This proposal allows you to check if a variable or statement is undefined or null and return a fallback value if it is.

/* New Syntax */
const one = undefined ?? 'Fallback'; // 'Fallback'
const two = null ?? 'Fallback'; // 'Fallback'

/* Old Syntax */
const one = undefined || 'Fallback';
const two = null || 'Fallback';

From looking at the above examples, you might think the Null Coalescing operator is totally unnecessary because it does the same thing as the OR operator. But they behave differently.

/* The differences between ?? and ||  */

const diffOne = 0 ?? 'Fallback'; // 0
const diffOne = 0 || 'Fallback'; // 'Fallback'

const diffTwo = '' ?? 'Fallback'; // ''
const diffTwo = '' || 'Fallback'; // 'Fallback'

const diffThree = false ?? 'Fallback'; // false
const diffThree = false || 'Fallback'; // 'Fallback'

How it works: The null coalescing operator returns the first thing that isn't null or undefined.

This is different from the way we usually check variables using || because the OR operator returns the first thing that's truthy. This means that if the value is false, an empty string, or null, it will not be returned; That can be a problem if one of those (false, null, empty string) is a valid value.

Do Block

The "do block" is a very interesting proposal, but it takes some getting used to. The syntax is simple: you write do, and then in brackets code you'd like to be executed. This feature would allow you to do some cool things that have been hard (or seemed hacky) in the past. Like when you have complex criteria for how to define a variable:

/* New Syntax */
const x = do {
    if (foo()) { f() }
    else if (bar()) { g() }
    else { h() }
};

/* Old Syntax */
let x = foo() ? f() : bar() ? g() : h();

// OR 

let x = (() => {
    if (foo()) return f();
    else if (bar()) return g();
    else return h();
}();

As mentioned in the official proposal, this syntax is especially helpful when used in templating languages like JSX.

return (
  <nav>
    <Home />
    {
      do {
        if (loggedIn) {
          <LogoutButton />
        } else {
          <LoginButton />
        }
      }
    }
  </nav>
);

Replace All

Wait, why do we need this again? We were already able to do string.replace('this', 'that'), right? But, replace only replaced the first instance of a string, unless you used a Regex. Again, this features solves a common "small problem" and makes things easier, especially for beginners 😄.

const string = '248.434.5508';

/* New syntax */
string.replaceAll('.', '-'); // returns '248-434-5508'

/* Old syntax */
string.replace(/\./g, "-");

Learning More

If you're interested in learning more about any of these potential features, you can check out the links to the official proposals below, or you can review all of the JS proposals.

Top comments (2)

Collapse
 
fxedel profile image
Felix Edelmann

I really like the optional chaining operator and the null coalescing operator in Kotlin and I'd love to see them in JS. The latter is called "Elvis operator" (?:) in Kotlin, btw.

Collapse
 
jakedohm_34 profile image
Jake Dohm

Yeah, both of those are really cool and helpful features. Thanks for sharing about the "Elvis operator" I didn't know that!