While onboarding and learning a new codebase, I was introduced to the concept of a magic number.
In programming, a magic number is a direct usage of a number in code with no explanation of what the number means. On its own, a magic number has no meaning.
It's best to avoid using magic numbers in your code because the number by itself does not provide any meaning to what it is used for. The solution to the ambiguity of magic numbers is to make them named constants.
These are the benefits of declaring magic numbers as named constants:
ESLint has no-magic-numbers built in to help catch magic numbers.
Let's take a look at a magic number in action. In this example, we have breadPuns
, an array of strings. We call Lodash's samplesize
and pass in breadPuns
and 4
. Looking at this code, it's not obvious that the number 4
is the number of breadPuns
we want to return.
// import Lodash
import _ from 'lodash'
// Declare and initiate breadPuns, an array of strings
const breadPuns = [
"I hope these bread puns aren't falling flat...",
"I'm on a roll!",
"You're adoughable!",
"Wanna a slice of this? It's the yeast I could do.",
"I'm all doughed out.",
'Loaf it!',
"You're just what I knead!",
'That toast is toastally delicious!',
'Stop loafing around!',
'Are these bread buns rising to the occasion?',
'You look loafly today!',
]
// Call sampleSize on breadPuns and 4 (magic number)
_.sampleSize(breadPuns, 4)
Since the magic number, 4
, doesn't provide us with any meaning, let's make it a named constant, NUM_SUGGESTED_PUNS
. This let's anyone reading the code know that 4
represents the number of suggested puns we want to return.
// Declare and initiate the magic number, 4, as a named constant
const NUM_SUGGESTED_PUNS = 4
_.sampleSize(breadPuns, NUM_SUGGESTED_PUNS)
Let's add another array, cheesePuns
. This time, we call sampleSize
twice, on breadPuns
and cheesePuns
. We also pass in NUM_SUGGESTED_PUNS
both times. Now, NUM_SUGGESTED_PUNS
is used twice in our code. Let's say we want to return 5 puns instead of 4 puns. We can easily update NUM_SUGGESTED_PUNS
to equal 5. Since the number is in a named constant, we only need to make one change for code that is used twice.
Imagine if NUM_SUGGESTED_PUNS
is used more than twice in our code. We'll still only need to update it once if we decide to change the value. Easy brie-zy.
// Declare and initiate cheesePuns, an array of strings
const cheesePuns = [
"This may sound cheesy, I think you're grate.",
'Oh no! I cut myself, it was sharp cheddar.',
"I hope you're having a gouda day.",
"I'm mature for my age.",
'Whisper words of wisdom, let it brie.',
'You make me melt.',
'I would be so provolone without you.',
'To brie, or not to brie.',
"Hey, you're looking sharp.",
]
// Update named constant to 5
const NUM_SUGGESTED_PUNS = 5
_.sampleSize(breadPuns, NUM_SUGGESTED_PUNS)
_.sampleSize(cheesePuns, NUM_SUGGESTED_PUNS)
A magic number is a number in code with no clear meaning to the reader. Magic numbers should be avoided. They should instead be replaced with named constants. This helps with readability and maintainability.
Resources: