Refactoring Magic Numbers

Magic numbers are numbers that appear in your source code without any explanation of what they stand for. Usually, this is because they are used directly rather than being referenced as a variable or constant.

Magic numbers make code difficult to understand, as there's no explanation of what the number stands for or how it was determined.

Here's an example of a magic number:

if (person.assets > 1000000) {
     person.investInStartup();
}

Why only invest in startups when you have more than one million dollars in assets? What does that value represent?

Giving a name to the number makes it easier to understand the code:

var ACCREDITED_INVESTOR_MINIMUM_ASSETS = 1000000;
if (person.assets > ACCREDITED_INVESTOR_MINIMUM_ASSETS) {
     person.investInStartup();
}

(Using ALL_CAPS is a common naming convention for constants.)

In the US, one million dollars in assets gives you Accredited Investor status. Giving this number a name explains what it stands for and why its value is one million.

Replacing magic numbers with constants also makes it easy to change the value in the future. If the asset threshold changes you can update ACCREDITED_INVESTOR_MINIMUM_ASSETS in one place.

With a magic number, you would have to search your code for the value and replace each occurrence individually. This isn't only extra work but also increases the potential for errors.

Magic numbers make code difficult to read and maintain. Always create a named variable that explains the meaning behind the number.

0, 1, -1, 2

These are not generally considered magic numbers, and it's ok to have them in your code. However, it's often possible to add more context to explain why you're using these numbers.

For example, you could introduce a new one-line function with a meaningful name.

Instead of comparing the result of indexOf to -1, you could create a listContains function that wraps around these specifics.

Similarly, you can replace number % 2 === 0 with an isEven function.

In these cases, it's not necessary to create a constant for -1 or 2. The single-line functions listContains and isEven already give enough context to explain the role of these numbers.

(I've also written a separate article discussing examples where 2 is a magic number and where it isn't.)

Preserve calculations inside your code

If you're calculating the value of a number, keep the original calculation instead of just pasting the result into your code.

Take this constant as an example:

var ONE_HOUR = 3600000;

Creating a ONE_HOUR constant is much better than using 3.6 million as a magic number. It explains what the number stands for.

To further improve the readability of your code you can include the original calculation:

var ONE_HOUR = 60 * 60 * 1000;

This allows other developers to not only see what the number means, but also understand how it was determined.

It also further clarifies that ONE_HOUR represents the number of milliseconds in one hour.