Categories
JavaScript Best Practices

JavaScript Best Practices — Spread, Rest, and Promises

Spread the love

To make code easy to read and maintain, we should follow some best practices.

In this article, we’ll look at some best practices we should follow to make everyone’s lives easier.

Replace the Use of the RegExp Constructor in favor of Regular Expression Literals

Regex literals are much shorter than using the RegExp constructor.

So we should use them in favor of the constructor.

For instance, instead of writing:

new RegExp("^\d.$");

We write:

/^\d.$"/

Using the Rest Parameters Instead of arguments

The argyments object doesn’t work with arrow functions and it’s not an array.

Rest parameters return an array of the arguments.

So we should use that instead.

For instance, instead of writing:

function foo() {
  console.log(arguments);
}

We write:

function foo(...args) {
  console.log(args);
}

Use Spread Syntax Instead of .apply()

We should use the spread syntax instead of apply .

For instance, instead of writing:

const args = [1, 2, 3, 100, 200\];
Math.max.apply(Math, args);

We write:

const args = [1, 2, 3, 100, 200];
Math.max(...args);

We don’t need apply unless we want to change the value of this .

Use Template Literals Instead of String Concatenation

We should use template literals instead of string concatenation.

It’s much easier to include expressions in template literals.

For instance, instead of writing:

const str = "hello, " + name + "!";

We write:

const str = `hello, ${name}!`;

Return Inside Each then() to Create Readable and Reusable Promise Chains

We should return something if we want to call then on the promise.

For instance, instead of writing:

myPromise.then(() => {
  doSomething()
})

We write:

myPromise.then(() => {
  return doSomething()
})

Use catch() on Un-returned Promises

We should use catch on unreturned promises to catch any errors to occur with them.

For instance, we can write:

myPromise
  .then(doSomething)
  .then(doMore)
  .catch(errors)

where errors is a callback to catch any error that occurred from the promises.

Make Sure to Create a Promise Constructor Before Using it in an ES5 Environment

The Promise constructor is introduced with ES6.

So any code written with older versions of ES must use a promise library to create promises.

For instance, instead of writing:

const x = Promise.resolve('foo');

We write:

const Promise = require('bluebird');
const x = Promise.resolve('foo');

No Nested then() or catch() Statements

We should avoid nested then or catch statements.

For instance, instead of writing:

myPromise.then(val =>
  doWork(val).then(doMore)
)

We write:

myPromise
  .then(doWork)
  .then(doMore)
  .catch(errors)

Avoid Using new on a Promise Static Method

If we are calling Promise static methods, then we shouldn’; use the new keyword.

For instance, instead of writing:

new Promise.resolve(value)
new Promise.reject(error)
new Promise.race([foo, bar])
new Promise.all([foo, bar])

We write:

Promise.resolve(value)
Promise.reject(error)
Promise.race([foo, bar])
Promise.all([foo, bar])

No return Statements in finally()

return statements in finally is useless since nothing will consume the result.

Therefore, instead of writing:

myPromise.finally((val) => {
  return val
})

We write:

myPromise.finally((val) => {
  console.log(val)
})

No Wrapping Values in Promise.resolve or Promise.reject when not Needed

We shouldn’t wrap values in Promise.resolve or Promis.reject when they aren’t needed.

For instance, instead of writing:

myPromise.then((val) => {
  return Promise.resolve(val * 3);
})
myPromise.then((val) => {
  return Promise.reject('foo');
})

We write:

myPromise.then((val) => {
  return val * 3
})
myPromise.then((val) => {
  throw 'foo'
})

return will return a promise with the resolved value being the return value.

throw will reject a promise with the given value.

Consistent Parameter Names when Creating New Promises

We should have consistent parameter names when creating new promises.

This way, there won’t be any confusion as to what they do.

For instance, instead of writing:

new Promise((reject, resolve) => { ... })

which have the functions in the wrong order or:

new Promise((ok, fail) => { ... })

which have nonstandard names, we write:

new Promise((resolve, reject) => { ... })

Prefer async/await to the Callback Pattern

async and await is shorter than the callback pattern, so we can sue that instead.

For instance, instead of writing:

myPromise
  .then((val) => {
    return foo();
  })
  .then((val) => {
    return bar();
  })
  .then((val) => {
    return val;
  })

We write:

const foo = async () => {
  const val1 = await myPromise;
  const val2 = await foo();
  const val3 = await bar();
  return va3;
}

Conclusion

We should use spread and rest instead of apply and arguments .

Promises can be cleaned up in many ways.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *