JavaScript is a very forgiving language. It’s easy to write code that runs but has mistakes in it.
In this article, we look at some mistakes that people make with conditionals and code blocks.
Duplicate Conditions in if-else-if Chains
We should be careful not to have 2 or more else if
blocks with the same condition. This leads to confusion and it’s almost always a mistake. They’ll all evaluate to the same truth value and the later ones will never run.
For instance, if we have:
let x;
const a = false;
const b = true;
if (a) {
x = 0;
} else if (b) {
x = 1;
} else if (b) {
x = 2;
}
Then we’ll see that x
is 1 because of the short-circuit evaluation. b
is true
, so that first else if
block that checks for b
is run.
Therefore, we should always have different conditions for each else if
block. For instance, we should write:
let x;
const a = false;
const b = false;
const c = true;
if (a) {
x = 0;
} else if (b) {
x = 1;
} else if (c) {
x = 2;
}
We should also be careful of duplicates that are caused because of the ||
and &&
operator. For instance:
let x;
const a = false;
const b = true;
if (a) {
x = 0;
} else if (b) {
x = 1;
} else if (a || b) {
x = 2;
}
It’s also a duplicate because the last if
block’s condition is either the same as a
or b
.
Duplicate Keys in Object Literals
Duplicate keys should never be in object literals. It’s more typing that doesn’t do any good.
For example, the following object:
const foo = {
bar: 1,
bar: 2
};
is the same as { bar: 2 }
. The first one is discarded. Other examples include:
const foo = {
bar: 1,
'bar': 2
};
or:
const foo = {
1: 'foo',
'1': 'bar'
};
Duplicate Case Labels
We shouldn’t have duplicate case
labels in our switch
statements. For instance, if we have:
const a = 1;
let foo = '';
switch (a) {
case 1:
foo = 'a';
break;
case 2:
foo = 'b';
break;
case 1:
foo = 'c';
break;
default:
break;
}
Then foo
is 'a'
since the switch
statement stops evaluating when it encounters the first matching case.
Therefore, the duplicate case
label is useless. Instead, we should write:
const a = 1;
let foo = '';
switch (a) {
case 1:
foo = 'a';
break;
case 2:
foo = 'b';
break;
default:
break;
}
Empty Block Statements
Empty block statements are useless. Therefore, we shouldn’t include them. For instance:
if (x === 1) {}
We should run something if we have a block.
Empty Character Class in Regex
An empty character class in regex doesn’t match anything, so it probably shouldn’t be in the code. For instance, we write:
const foo = /^foo[]/;
The []
doesn’t do anything so it should be removed.
Reassigning Exceptions in catch Clauses
We shouldn’t reassign the exception object passed in from catch
to something else since it obscures the source of the original error. If we assign it to something else, then we wouldn’t be able to determine the origin of the error from this point on.
For instance, if we write:
try {
// ...
} catch (e) {
e = 'foo';
}
Then e
becomes 'foo'
after the assignment. Then we won’t know what e
is originally after the reassignment.
Instead, we should assign 'foo'
to another variable as follows:
try {
// ...
} catch (e) {
let foo = 'foo';
}
Then e
has the same value and before and we can also reference 'foo'
.
Conclusion
We should never have duplicate conditions in multiple else-if
blocks since only the first one in the group of duplicates will do something. This also applies to case
labels.
Object key literals also shouldn’t be duplicated since only the last one’s value will remain.
Other useless codes include empty code blocks and empty regex classes.
Finally, we shouldn’t reassign the exception parameter to another value since the original exception value will begone. Instead, we should create a new variable and assign whatever we want to it.