JavaScript Best Practices — Things to Avoid
Tags: codequality, webdev, programming, javascript
Published: 2021-01-27 00:00:39

**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/**

Like any other programming language, JavaScript has its own list of best practices to make programs easier to read and maintain. There are lots of tricky parts to JavaScript, so there are many things to avoid.

We can follow some best practices easily to make our JavaScript code easy to read.

In this article, we look at things to avoid, including declaring global variables whenever possible, passing strings to `setInterval` and `setTimeout`, the `with` statement, and more.

* * *

### Avoid Declaring Global Variables

We should avoid the use of global variables as much as possible for various reasons.

One is that they’re easy to overwrite in different places since they’re available everywhere. They can also overwrite things in the `window` object since global variables are properties of the `window` object.

These two are real issues that make our code hard to follow. Therefore, we should define local variables as much as possible.

We can define local variables by using the `var`, `let`, or `const` keywords.

Variables defined with `var` are available at the level where it’s defined and below before it’s defined. For example, if we write:

```
const log = () => {
  console.log(x);
}
log();
var x = 1;
log();
```

Then we get `undefined` for the first `console.log` and one for the second log.

It’s the same as writing:

Variables declared with `let` are available only after they’re defined, so if we give:

```
const log = () => {
  console.log(x);
}
log();
let x = 1;
log();
```

We get the error:

```
Uncaught ReferenceError: Cannot access ‘x’ before initialization
```

With the `const` keyword, we define constants that can only be assigned once and never again. It’s also available only after it’s declared unlike `var`.

For example, we can write:

```
const log = () => {
  console.log(x);
}

const x = 1;
log();
```

Calling `log` before `const x = 1` will also get us `Uncaught ReferenceError: Cannot access ‘x’ before initialization`.

If we want variables that are available in different parts of a program, we should use JavaScript modules and then build the modules into one or several large files when we release our code. This has been available since ES6.

We can `export` our variables and `import` them into other modules. There’s also `export default` to export the whole module. This way, we only export things that should be available outside the module and keep everything else private.

We can also use closures to keep variables inside a function so they can’t be accessed outside. An example of a simple closure would be:

```
const divide = () => {
  const x = 3;
  return () => x * 2;
}
```

We keep `x` inside the `divide` function so that it can’t be accessed outside and return a function that does something with it.

Then we call it by writing:

```
console.log(divide()());
```

![](https://cdn-images-1.medium.com/max/800/0*SAFNVI7sYUItR9iE)Photo by [Matt Jones](https://unsplash.com/@mattrobinjones?utm_source=medium&utm_medium=referral) on [Unsplash](https://unsplash.com?utm_source=medium&utm_medium=referral)

* * *

### Never Pass a String to setInterval or setTimeout

We should never pass strings to the first argument of the `setInterval` or `setTimeout` functions instead of a callback function.

If we pass a string into it instead of a callback function, the browser will use `eval` to run the code inside the string, which is slow and it’s vulnerable to code inject attacks.

Therefore, there’s no reason unless we really need to run code that’s generated on the fly, which should be very, very rare.

Instead of writing:

```
setTimeout(
  "document.getElementById('foo').textContent = 'foo'", 1000
);
```

We should write:

```
setTimeout(() => {
  document.getElementById('foo').textContent = 'foo';
}, 1000);
```

* * *

### Don’t Use the “with” Statement

On the surface, the `with` statement may seem like a good shortcut for accessing deeply nested properties of objects. For example, we can write:

Instead of:

However, it pollutes the global scope and creates ambiguity of whether `baz` is accessible outside the `with` statement. This is because we can also declare new variables inside the `with` statement:

We declared `baz` inside `with`, but it isn’t accessible outside.

Fortunately, it’s not allowed to be used in JavaScript strict mode so we don’t have to worry about using the `with` statement now.

* * *

### var Keyword

With ES6, we have the block-scoped `let` and `const` keywords for declaring variables and constants respectively. We can use them to declare variables since they have a clear scope.

Variables declared with `var` has a confusing scope. It’s available outside of blocks when it’s declared in a block like an `if` block or a loop.

Something like:

```
for (let i = 0; i < 10; i++){
  var j = i;
}
console.log(j);
```

Works with `var`, but we would get an error if we replace `var` with `let`.

Because the scope is confusing, we should stop using `var` to declare variables.

* * *

### Conclusion

When we write JavaScript, we want to avoid many older constructs that existed in early versions of JavaScript. They make our code hard to read and it’s easy to create bugs with it.

First, we want to avoid global variable declarations to avoid referencing and declaring things accidentally in the global scope. It also reduces the chance of modifying a global variable’s values accidentally.

We also should stop passing in code in a string instead of passing in a callback function to the first argument of the `setTimeout` and `setInterval` functions. This is because `eval` will be used to run the code stored in a string, which exposes our code to code injection attacks and it’s also slow.

Also, we should avoid the `with` statement because it creates variables in the global scope.

Likewise, because of the confusing scope of variables declared with the `var` keyword, we should avoid declaring variables with the `var` keyword.