JavaScript Best Practices: Useless Code, Comparisons, and Eval
Tags: codequality, webdev, programming, javascript
Published: 2021-01-27 02:12:47

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

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 some JavaScript best practices to follow, including avoiding empty function and destructuring, null comparison, avoiding useless `bind` and avoid `eval`.

* * *

### Don’t Write Empty Functions

Empty functions aren’t useful and we don’t know if they’re intentional or not. This means that we should at least write a comment to let people know whether it’s intentional.

This also goes for arrow function callbacks that return nothing, since they look similar to an empty object.

For instance, we should avoid:

```
function foo() {}
arr.map(() => {});
arr.map(() => ({}));
```

Instead, we should write:

```
function foo() {
  // do nothing
}
```

or:

```
arr.map(() => {}); // returns nothing
```

or:

```
arr.map(() => ({})); // returns empty object
```

* * *

### Empty Destructuring Patterns

Empty destructuring patterns are also useless, so there’s no point in creating them. For instance, the following isn’t useful:

```
const {a: {}} = foo;
```

It might also be mistaken for setting `a` to an empty object as the default value as follows:

```
const {a = {}} = foo;
```

We should avoid having empty destructuring patterns in our code. If we have any, we can and should remove them.

* * *

### Null Comparisons with ==

`null` comparisons with `==` or `!=` also compares the operand we’re comparing with other values with `undefined` . Therefore, the following are also `true` if we compare `foo` with `null` in the following code:

```
let foo = undefined;
foo == null;
```

We get that `foo == null` returns `true`, which is probably not what we want. Likewise, if we have the following comparison with `!=`:

```
let foo = undefined;
foo != null;
```

We get that `foo != null` is `false` even though `foo` is `undefined` . Therefore, we should instead use `===` and `!==` to check for `null` as follows:

```
let foo = undefined;
foo === null;
```

and:

```
let foo = undefined;
foo !== null;
```

* * *

### Never Use eval()

`eval` lets us pass in a string with JavaScript code and run it. This is dangerous because it can potentially let anyone run JavaScript code that we didn’t write. It can open up our program to several kinds of injection attacks.

* * *

### No Extension of Native Objects

In JavaScript, we can extend any native objects with their own methods. However, that’s not a good idea because it may break other pieces of code that use native objects in ways that we don’t expect.

For instance, if we have the following:

```
Object.prototype.foo = 55;

const obj = {
  a: 1,
  b: 2
};

for (const id in obj) {
  console.log(id);
}
```

We see that `foo` is logged in addition to `a` and `b` because the `for...in` loop iterates through all enumerable properties in the current object and the object’s prototype chain.

Since JavaScript extends the JavaScript`Object` object by default, the `for...in` loop will also loop through enumerable properties in the `Object`’s prototype.

Therefore, we shouldn’t extend native objects as it may do things that we don’t expect to other code.

* * *

### No Unnecessary Function Binding

The `bind` method is a method of a function that changes the value of `this` inside a traditional function. Therefore, if our function doesn’t reference `this`, then we don’t need to call `bind` on it to change the value of `this`.

For example, the following function uses `bind` with a purpose:

```
function getName() {
  return this.name;
}
const name = getName.bind({
  name: "foo"
});
console.log(name());
```

In the code above, we have the `getName` function, then we called `bind` on it to change the value of `this` to `{ name: “foo” }`. Then we when we call `name` in the last line, we see return `this.name` , which should be `'foo'` since we changed the value of `this` to the object.

On the other hand, if we have:

```
function getName() {
  return 'foo';
}
const name = getName.bind({
  name: "foo"
});
console.log(name());
```

Then the call to `bind` is useless since `getName` didn’t reference `this`. Therefore, if our function doesn’t reference `this`, then we don’t need to call `bind` on it.

* * *

### Conclusion

Comparing `null` with `==` isn’t very useful since expressions like `undefined == null` also return `true` because of type coercion. To ensure attackers can’t run malicious code, `eval` shouldn’t be called.

`bind` is useless if we don’t reference `this` in our function, so if we do call it, we should make sure that we have `this` in our function. Other things like empty functions and destructuring patterns are useless, so they should be avoided.