Categories
JavaScript Best Practices

JavaScript Best Practices — 12 Useless Statements You Should Avoid

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 Dangling Underscores in Identifiers

Dangling underscores are used for identifying private variables whether they’re actually private or not.

It’s best not to use this since if they’re not private, people may think it’s private.

So instead of writing:

foo._bar();

We write:

foo.bar();

No Confusing Multiline Expressions

We should separate statements and expressions with semicolons when they need to be separated.

For instance, we shouldn’t code like:

const foo = bar
[1, 2, 3].forEach(log);

We don’t know if the 2 lines should be together or not.

Instead, we write:

const foo = bar;
[1, 2, 3].forEach(log);

to separate them clearly.

No Unmodified Conditions of Loops

We shouldn’ have unmodified conditions in loops.

This creates infinite loops, which probably don’t want.

For instance, we shouldn’t write:

while (item) {
  doWork(item);
}

Instead, we write:

for (let j = 0; j < items.length; j++) {
  doWork(items[j]);
}

No Ternary Operators when Simpler Alternatives Exist

We shouldn’t use ternary expressions when there’re simpler alternatives.

For instance, we shouldn’t write:

const isOne = answer === 1 ? true : false;

Instead, we write:

const isOne = answer === 1;

We don’t need to write true and false explicitly.

No Unreachable Code After return, throw, continue, and break Statements

We shouldn’t have unreachable code after return , throw , continue , and break statements since they’ll never be run.

For instance, instead of writing:

function foo() {
  return true;
  console.log("end");
}

We write:

function foo() {
  return true;
}

No Control Flow Statements in finally Blocks

We shouldn’t have control flow statements like return statements in finally blocks.

Instead, we should put them elsewhere.

Control flow statements are suspended until finally runs.

So the control flow statements in try or catch will be overwritten with the one in finally .

Therefore, instead of writing:

try {
  return 1;
} catch (err) {
  return 2;
} finally {
  return 3;
}

We write:

try {
  return 1;
} catch (err) {
  return 2;
} finally {
  console.log('finally');
}

No Negating the Left Operand of relational Operators

We shouldn’t negate the left operand of relational operators since they only negate the operand and not the whole expression.

For instance, instead of writing:

if (!key in obj) {
  // ...
}

We write:

if (!(key in obj)) {
  // ...
}

No Unused Expressions

If an expression isn’t used, then we should remove them.

For instance, we shouldn’t write:

{0}

or:

c = a, b;

instead, we write:

f()

or:

a = 0

etc.

No Unused Variables

If we have unused variables, we should remove them.

So if we have:

var x;

and it isn’t used anywhere else, then we should remove them.

No Early Use of Variables and Functions

We shouldn’t use variables or functions before they’re declared in our code.

For instance, we can write:

console.log(a);
var a = 10;

or:

f();
function f() {}

We can use function declarations and variables before they’re declared.

Function declarations can be called, but variables will be undefined if they’re used before they’re declared.

To remove confusion, we should write:

var a = 10;
console.log(a);

and:

function f() {}
f();

No Unnecessary .call() and .apply()

We shouldn’t use call and apply unnecessarily.

If we don’t change the value of this , then we shouldn’t use them.

Instead, we just call it directly.

So instead of writing:

foo.call(undefined, 1, 2, 3);
foo.apply(undefined, [1, 2, 3]);
obj.foo.call(obj, 1, 2, 3);
obj.foo.apply(obj, [1, 2, 3]);

We write:

foo(1, 2, 3)
obj.foo(1, 2, 3)

No Unnecessary catch Clauses

If our catch clause only rethrows an exception, then we don’t need them.

So we shouldn’t write:

try {
  doWork();
} catch (e) {
  throw e;
}

try {
  doWork();
} catch (e) {
  throw e;
} finally {
  cleanUp();
}

We write:

try {
  doWork();
} catch (e) {
  handleError(e);
}
try {
  doWork();
} catch (e) {
  handleError(e);
} finally {
  cleanUp();
}

Conclusion

We shouldn’t write useless statements.

They make our code more complex and are redundant.

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 *