Categories
JavaScript Best Practices

JavaScript Best Practices — Duplicates, Returns, Eval, and Built-in Prototypes

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.

No Duplicate Conditions in if-else-if Chains

We shouldn’t have duplicate conditions in if-else-if chains.

Only the first one will run.

So instead of writing:

if (isSomething(x)) {
  foo();
} else if (isSomething(x)) {
  bar();
}

We write:

if (isSomething(x)) {
  foo();
} else if (isSomethingElse(x)) {
  bar();
}

No Duplicate Keys in Object Literals

We shouldn’t have duplicate keys in object literals.

For instance, we shouldn’t have objects like:

const foo = {
  bar: "baz",
  bar: "bar"
};

Instead, we write:

const foo = {
  bar: "baz"
};

No Duplicate Case Label

We shouldn’t have duplicate case labels in our code.

For instance, instead of writing:

switch (a) {
  case 1:
    break;
  case 2:
    break;
  case 1:
    break;
  default:
    break;
}

We write:

switch (a) {
  case 1:
    break;
  case 2:
    break;
  default:
    break;
}

No Duplicate Imports

We shouldn’t have multiple, import statements for one module.

For instance, instead of writing:

import { merge } from 'module';
import something from 'foo';
import { find } from 'module';

We write:

import { merge, find } from 'module';
import something from 'foo';

No return Before else

If we’re writing a return statement, then we can remove the else

For instance, we can write:

function foo() {
  if (x) {
    return y;
  }
  return z;
}

instead of writing:

function foo() {
  if (x) {
    return y;
  } else {
    return z;
  }
}

No Empty Block Statements

Empty blocks aren’t very useful, so we should fill them with something or remove them.

For instance, the following aren’t very useful:

if (bar) {}

while (bar) {}

switch (bar) {}

try {
  doSomething();
} catch (ex) {

} finally {

}

for (;;){}

Instead, we fill them with something.

Empty Character Classes in Regex

We shouldn’t have empty character classes in regex since they don’t match anything.

For instance, we should have code like:

/^foo[]/.test("foobar");
"foobar".match(/^foo[]/);

Instead, we should fill the brackets with a pattern:

/^foo[a-z]/.test("foobar");
"foobar".match(/^foo[a-z]/);

No Empty Functions

We shouldn’t have empty functions in our code.

They don’t do anything.

For instance, instead of writing:

function foo() {

}

We write:

function foo() {
  doSomething();
}

No Empty Destructuring Patterns

Empty destructuring patterns do nothing, and they’re easily mistaken for empty objects as the default value.

For instance:

const {a: {}} = foo;

is easily mistaken for:

const {a = {}} = foo;

The first is an empty destructuring pattern.

The 2nd is using the empty object as the default value.

No Null Comparisons

Comparing null using == or != can have unintended consequences because of the data type coercion.

Therefore, we should use === or !== to do the comparison.

Instead of writing:

if (foo == null) {
  bar();
}

while (qux != null) {
  bar();
}

We write:

if (foo === null) {
  bar();
}

while (qux !== null) {
  bar();
}

No Calls to eval()

eval lets us run JavaScript code from a string.

But we shouldn’t use it since it’s insecure to run code from a string.

Performance optimizations also can’t be done on code that’s in a string.

Instead of writing:

eval("let a = 0");

We write:

let a = 0;

No Reassigning Exceptions in catch Clauses

We shouldn’t reassign exceptions ib catch clauses.

If we do, then we lose data from the exception.

So instead of writing;

try {
  // code
} catch (e) {
  e = 10;
}

We write:

try {
  // code
} catch (e) {
  const foo = 1;
}

Don’t Extend Native Objects

We shouldn’t extend built-in objects, even though we’re allowed to.

For instance, we shouldn’t write code like:

Object.prototype.foo = 55;

to add properties to a built-in constructor.

Using defineProperty is also bad:

Object.defineProperty(Array.prototype, "bar", { value: 999 });

Conclusion

We shouldn’t have duplicate conditions, keys, or case labels.

Also, we should never use eval .

And we shouldn’t extend native objects.

Empty destructuring patterns are also useless and deceptive.

We should compare null with === or !== .

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 *