- They haven't really been a problem for me. I usually only encounter one or two magic numbers, max, per module, and many don't have any, so they're not that hard to deal with. Other projects may be different though.
- By putting them in a constant at the top of the module. Or, sometimes at the top of the function if they only relate to the logic within that function. The same thing applies for any magic value, like magic strings as well.
- We don't have any official design guide that talks about magic numbers, but we all seem to be on the same page on how to handle them. And, I would very much be against a linter rule for this sort of thing.
The problem with linter rules, is that they'll just flag way too many numbers as "that's magic, put it into a constant to make it easier to understand", when really, those numbers can be understood just fine. Some examples that it would flag, that really don't need go into constants:
const secondsToMinutes = sec => sec/60
const radiansToDegrees = rad => rad * 180/Math.PI
initSessionTimeout({
minsOfAllowedInactivity: 5,
})
And these are examples that really arguably don't need to be put into a constant, unless you realize that more than one place needs these values. You could put them in a constant if you think that's likely to happen, but there's often no real reason to do so until it's needed. Perhaps there's other ways to improve this code (like, adding a comment explaining what's going on, refactoring out a chunk, etc), so it's also important to keep in mind that simply putting the number into a constant isn't always the best solution, it's just one possible solution to clean up code.
myElement.style.marginLeft = '5px'
function countdownInSeconds({ startingAt, onTick }) {
let secLeft = startingAt
const intervalId = setInterval(() => {
secLeft--
onTick(secLeft)
if (secLeft <= 0) clearInterval(intervalId)
}, 1000)
})
// If everyone on your team is familiar with node's process.argv
// then this logic should feel pretty natural. If you're writting the
// code for people who might not be familiar, then a comment
// explaining what's going on would do much better then putting
// the `2` in a constant.
if (process.argv.length === 2) {
console.error('Please provide a required parameter')
} else {
const requiredArg = process.argv[2]
...
}
// You could create a constant for the length of the id, but if the length really
// isn't important to your code, then that's just unecessary noise.
const randomId = Math.random().toString().slice(2, 7)
Linter rules should be about making your code style consistent, and flagging real bugs that it finds (or the use of unnecessary footguns). This sort of linter rule falls out of both of those categories, and instead is trying to do a really bad job at helping you decide what code is unreadable and needs fixing up. In some cases, this will just lead you to placing a number of // eslint-disable-line
comments around to let the linter know "thank you for that helpful hint, but I don't think it's going to help here". In other cases, you'll just extract a constant to make the linter shut up, even though it's really not needed, so all you're doing is busy work.
I know some people feel like the most important aspect of magic numbers are about making sure you're not repeating that number (i.e. keeping your code DRY), and yes, it can be important to DRY up your numbers, but again, that feels like something that's better left for the programmer to decide when to DRY their code and when not to (like they have to do whenever they decide it's appropriate to DRY up any other logic).
Anyways, there's my rant on magic numbers. If you find that you're having to extract a ton of constants in your own code (perhaps because of a linter, or team rules), maybe take a second look at those constants you're extracting and ask yourself if that really needed to be done. Because, it's very possible that a lot of those "magic numbers" would have worked just fine if you simply left them as-is in your code, without turning them into a constant. Perhaps, this is the reason why you're finding magic numbers cumbersome to work with, because you're dealing with an overly strict policy on turning them into constants, and are needing to turn far too many numbers into constants.