JavaScript Best Practices — Modern Syntax

John Au-Yeung - Jan 27 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

There are better ways to write JavaScript code than others.

In this article, we’ll look at the best practices for using the latest JavaScript syntax features.

Syntactic Sugar

In JavaScript, the syntactic sugar that’s included is usually good.

They let us write code in a shorter and clear way and make them more readable in the process.

These syntactic sugars are drop-in replacements for existing techniques so we should use them.

const Isn’t Consistent

const is a keyword for declaring block-scoped constants.

They’ll make primitive values assigned to it immutable since we can’t assign a constant again after it’s assigned to a value.

A value must be assigned when we declare it.

However, const is a bit deceptive since some people might not know that we can still change objects that are assigned to const by changing their properties.

Also, arrays can be changed in place with methods like push and unshift .

Therefore, we shouldn’t assume that objects that are assigned to const are immutable.

Limiting the Scope of the Function

Traditional functions defined with the functionm keyword can be called to run statements defined in the block and may return a value.

They can be run anywhere if they’re written as a function declaration.

For instance, if we have:

function foo() {
  //...
}
Enter fullscreen mode Exit fullscreen mode

Then foo can be run before or after it’s defined.

It also defines its own this and can be used with the new operator as a constructor.

So, to limit the capabilities of our functions, we should use arrow functions.

If we need constructors, then we should use the class syntax to define them to make everyone clear.

The Class Syntax

The class syntax is great for defining constructors. It does the same thing as the old constructor function syntax.

It looks like a class in an object-oriented language like Java, but it does the same thing as JavaScript constructors.

Therefore, the prototypical inheritance model is still used with JavaScript classes.

So the following:

function Person(name) {
  this.name = name;
};

Person.prototype.greet = function() {
  console.log(`hi ${this.name}`);
};
Enter fullscreen mode Exit fullscreen mode

is the same as:

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`hi ${this.name}`);
  }
}
Enter fullscreen mode Exit fullscreen mode

They hold and do the same thing but the placement of the fields and methods are different.

Arrow Functions

Arrow functions are great. They are shorter. Thet but more neatly in callbacks.

It can return without adding the return keyword if we return in the first line.

They encapsulate qualities that make them more convenient. But they aren’t a drop-in replacement for traditional functions defined with the function keyword.

We can call bind by to change this inside a function.

Also, we can’t call call and apply with them to change this and call functions with arguments with them.

Going Asynchronous

Going async with JavaScript has its own difficulty because of JavaScript’s single-threaded nature.

We’ve to write code that unblocks the thread so that they won’t hold up our programs until we’re ready to run them.

This is where async code with callbacks come in to make calling async code easier.

We can make our code async by calling setTimeout . Also, pretty much any HTTP client runs in an async manner.

If we have lots of async code with callbacks, then we have to nest callbacks.

This gets ugly real fast.

If we use callbacks for chaining async code, we may have code that looks like this:

async1((err, res) => {
  if (!err) {
    async2(res, (err, res) => {
      if (!err) {
        async3(res, (err, res) => {
          //...
        });
      }
    });
  }
});
Enter fullscreen mode Exit fullscreen mode

That’s ugly and just not maintainable. Instead, we use promises. Then we can write something like:

promise1
  .then((res) => {
    //...
    return promise2
  })
  .then((res) => {
    //...
    return promise3
  })
  .then((res) => {
    //...
  })
Enter fullscreen mode Exit fullscreen mode

That’s much cleaner than nesting async callbacks with the previous example.

We can make things even shorter by writing:

(async () => {
  const val1 = await promise1;
  //...
  const val2 = await promise2;
  //...
  const val3 = await promise3;
  //...
})();
Enter fullscreen mode Exit fullscreen mode

As we can see, the code is much shorter and it’s exactly the same as the promise chain we have before.

The only difference is that va11 , val2 , and val3 hold the resolved values of the promises instead of res .

Conclusion

We got to know some things about JavaScript like how const aren’t always immutable, and clean up async code with async and await.

Also, arrow functions and classes should be used for regular functions and constructors respectively.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .