Categories
JavaScript Best Practices

JavaScript Best Practices- Loops and Useless Expressions

Spread the love

JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.

In this article, we’ll look at loops that we shouldn’t have, and useless labels, catch clauses, and call and apply calls that are useless.

No Unmodified Loop Conditions

If we have a while or do...while loop with an unmodified condition, the loop will run forever as the loop condition hasn’t been updated with a new value.

This is usually not what we want as it’ll crash our program most of the time because of the infinite loop.

However, infinite loops are sometimes appropriate for functions like generator functions that return the latest value when the generator is created from the function and invoked.

Therefore, in a regular while loop, we probably shouldn’t write an infinite loop:

while (condition) {
    doSomething();
}

However, it’s appropriate for generator functions that return an infinite number of entries:

function* num() {
  let i = 1;
  while (true) {
    yield i;
    i++;
  }
}

const iterator = num();
const val = iterator.next().value;
const val2 = iterator.next().value;

In the code above, we have the num generator function while returns a new integer after we created an iterator from it by calling it, and then calling next on it one or more times to get the value one at a time.

For regular while or do...while loops, we should almost always have a condition that changes.

For instance, we can write the following:

let x = 1;
while (x <= 5) {
  console.log(x);
  x++;
}

The code above has a condition that ends the loop as we increase x by 1 until x is 5.

No Unused Expressions

Some JavaScript expressions in our code are useless as it doesn’t do anything. For instance, if we have the following code:

x + 1;

Then it doesn’t do anything since we didn’t assign it to a variable and we didn’t return it in a function.

With build tools, expressions like these may be eliminated and break application logic.

Also, sequence assignment expressions like x = 1, y = 2 are always useless unless we return the values, assign them to another variable somewhere else, or do some manipulation with it later.

No Unused Labels

Unused labels are useless since they aren’t used anywhere. Therefore it’s dead code that’s just taking up space.

For instance, if we have the following:

loop:
  for (let i = 1; i <= 5; i++) {
    console.log(i);
  }

Either we should use it or we should remove it. We can use it as follows, for example:

loop:
  for (let i = 1; i <= 5; i++) {
    console.log(i);
    if (i === 2) {
      break loop;
    }
  }

We break the loop with the loop label with break loop when i is 2.

No Unnecessary .call() and .apply()

The call and apply method is only useful when we need to change the value of this in a function and call it with various arguments.

The following uses for it aren’t very useful:

function greet(greeting) {
  console.log(`${greeting} ${this.name}`);
}

greet.call(undefined, 'hi');

We passed in undefined to make this set to undefined . So it’s the same as calling greet('hi') directly.

Therefore, we don’t need to invoke the call method.

Likewise, the following apply call is also useless:

function greet(greeting) {
  console.log(`${greeting} ${this.name}`);
}

greet.apply(undefined, ['hi']);

It’s also the calling greet('hi') directly.

Instead, we should call greet with call or apply in ways that are useful.

For instance, we should call them as follows:

function greet(greeting) {
  console.log(`${greeting} ${this.name}`);
}

greet.apply({
  name: 'jane'
}, ['hi']);

greet.call({
  name: 'jane'
}, 'hi');

This way, we set the value of this inside the function to an object with the name property, so that this.name inside the function can be populated with the this.name .

We actually need to use call and apply to set the value of this in the example above.

Conclusion

Unmodified loop conditions are bad most of the time because it may cause crashes because of the infinite loop.

However, infinite loops are useful in generator functions that keep returning values with the returned iterator.

Unused labels for loops are useless and so it’s dead code that should be removed.

call and apply that are useless, like those that set the value of this to undefined since they are no different than calling the function directly.

Finally, we also shouldn’t have unused expressions in our code since it’s just more useless code that we can remove.

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 *