Actually, the code is more than one bad practice:
var a = 1; function myFunction() { ++a; // 1 return true; } if (myFunction() && a === 2) { // 2, 3, 4 alert("Hello, world!") } if (a === 3 && myFunction()) { // 2, 3, 4 alert("Hello, universe!") }
Mutates a variable in another area. This may or may not be a problem, but usually it is.
Calls a function inside the conditions of an if . This does not cause problems in itself, but it is not very clean. It is better to assign the result of this function to a variable, possibly with a descriptive name. This will help those who read the code to understand what exactly you want to check inside this if . By the way, the function always returns true .
Uses some magic numbers. Imagine someone else reading this code, and it is part of a large code base. What do these numbers mean? The best solution would be to replace them with well-known constants.
If you want to support more posts, you need to add additional conditions. A better approach would be to make this configuration.
I would rewrite the code as follows:
const ALERT_CONDITIONS = { // 4 WORLD_MENACE: 2, UNIVERSE_MENACE: 3, }; const alertsList = [ { message: 'Hello world', condition: ALERT_CONDITIONS.WORLD_MENACE, }, { message: 'Hello universe', condition: ALERT_CONDITIONS.UNIVERSE_MENACE, }, ]; class AlertManager { constructor(config, defaultMessage) { this.counter = 0; // 1 this.config = config; // 2 this.defaultMessage = defaultMessage; } incrementCounter() { this.counter++; } showAlert() { this.incrementCounter(); let customMessageBroadcasted = false; this.config.forEach(entry => { //2 if (entry.condition === this.counter) { console.log(entry.message); customMessageBroadcasted = true; // 3 } }); if (!customMessageBroadcasted) { console.log(this.defaultMessage) } } } const alertManager = new AlertManager(alertsList, 'Nothing to alert'); alertManager.showAlert(); alertManager.showAlert(); alertManager.showAlert(); alertManager.showAlert();
A class with an exact function that uses its own internal state, and not a bunch of functions that rely on some variable that can be located anywhere. Whether to use the class or not is a matter of choice. This can be done differently.
Uses configuration. This means that you want to add more messages, you do not need to touch the code at all. For example, imagine the configuration comes from a database.
As you can see, this changes the variable in the outer area of ββthe function, but in this case it does not cause any problems.
Uses constants with a clear name. (well, maybe better, but bring this example with me).
Giacomo cosimato
source share