JavaScript logical operators explained
I’m sure you are familiar with logical operators because you learned them in high school.
Let’s revise those concepts in a few paragraphs! This short summary will help you understand JavaScript logical operators.
and
Consider two simple statements and assume that both of them are true
, independent of each other:
Statement A: It’s sunny today. Statement B: I’m feeling good.
Now concatenate them into one statement, and let’s call it a master statement:
It’s sunny today and I’m feeling good.
We feel that the master statement is true
, since both statements, one by one, are true.
But if we negate one or both of the statements, the master statement becomes false
.
Why? If we negate statement A, our master statement looks like this:
It’s not sunny today and I’m feeling good.
The word and indicates that both statement A and statement B must be true
at the same time if we want our master statement to be true. and creates such a strong tie between the statements that the master statement immediately becomes false
once we change the logical value (i.e. the truthiness or falseness of a statement) of either A or B or both to false
.
or
Now we create a new master statement from statements A and B, this time we place the word or in between:
It’s sunny today or I’m feeling good.
Again, assume for a moment that both A and B are true
: The Sun is shining and I’m feeling utterly awesome. In this case the master statement is also true
.
What if we change the weather and say the following:
It’s not sunny today or I’m feeling good.
Am I lying when I declare that? No! The word or indicates that we have some freedom: One of the statements is still true
, so negating statement A won’t change the logical value of the whole master statement. or is less strict than and.
If it’s still not clear why the master statement is true, consider the following:
I’ll give away a million dollars or I’ll blink at least once in the next five minutes.
Do I lie when I’m saying that?
No. Of course, I’m not fool, so I won’t give away a million dollars, I don’t even have the money, so the first statement was a big fat lie (hence the logical value of giving away a million dollars is unfortunately false
). But the second part, the statement about blinking is true
! It has already happened since I wrote that line, so I didn’t lie at all.
Back to the original problem: What if we change the logical value of both A and B? The master statement will look like this:
It’s not sunny today or I’m not feeling good.
Now this master statement is false
, because however hard I’m trying to choose one true statement (either A or B), it’s not possible, both of them are false
.
Now let’s have a look at how JavaScript manages logical operators.
The &&
operator
It’s commonly believed that the &&
operator is the and in JavaScript but this is only half of the truth.
It’s true though that a statement including &&
is only true
if both left- and right-hand side operands are true
:
const a = true;
const b = true;
console.log(a && b); // true
const c = false;
const d = true;
console.log(c && d); // false
const e = true;
const f = false;
console.log(e && f); //false
const g = false;
const h = false;
console.log(g && h); // false
So far so good, high school math is working well in practice.
But the &&
operator is more than that: It’s checking the logical value (i.e. true
or false
) of the first operand (statement) and if that evaluates to true
, it will return the second operand. If the first operand can be converted to false
, it will return the first operand.
This is best shown in the following snippet:
const firstNumber = 3;
const secondNumber = 5;
console.log(firstNumber && secondNumber); // 5
firstNumber
is 3, which is a truthy value, so it’s converted to true
. Because the first statement is true
, the operator returns secondNumber
, which is 5.
Similarly, if the logical value of the first operand is false
, we’ll get it returned:
const falsyValue = 0;
console.log(falsyValue && secondNumber); // 0
Whatever the value of secondNumber
is (5 in this case), the operator returns the first statement (and not necessarily false
).
We could have written any falsy values instead of 0 as the first operand. For example, if we made falsyValue
equal to undefined
, the &&
operator would return undefined
and not false
.
The ||
operator
Similarly to &&
, the ||
operator partly corresponds to the or word in that sense that the truthiness of only one of the statements is enough for the master statement to become true:
console.log(a || b); // true
console.log(c || d); // true
console.log(e || f); // true
console.log(g || h); // false
The ||
operator is also more than that. It checks the value of the first operand and if it’s truthy, it will return the first operand. If the first operand can be converted to false
, it will return the second operand:
console.log(firstNumber || secondNumber); // 3
console.log(falsyValue || secondNumber); // 5
firstNumber
is truthy (it’s value is 3), so it will be returned. In the second example, falsyValue
is falsy, so the value of the second statement (secondNumber
) will be returned, so we will get 5.
As it can be seen, &&
and ||
behave in the opposite way.
Combining them
These operators can also be combined. Due to operator precedence, the &&
is “stronger” than ||
, which means that if both can be found in an expression, &&
should be read first:
const thirdNumber = 7;
console.log(firstNumber && secondNumber && thirdNumber); // 7
console.log(firstNumber && falsyValue && thirdNumber); // 0
console.log(firstNumber || secondNumber && thirdNumber); // 3
console.log(falsyValue || secondNumber && thirdNumber); // 7
The first example shows a case where all operands evaluate to truthy, so the returned value of the statement is thirdNumber
, i.e. 7.
The second example contains a falsy value. The reading direction is from left to right, so we first evaluate firstNumber && falsyValue
. firstNumber
can be converted to true
, so it returns the second operand (falsyValue
), which is 0. We already have a falsy value in the expression. Although thirdNumber
is truthy, it won’t change the result, so our second expression will return the falsy value (0).
In the third case the order of operators (operator precedence) suggests that we need to start with secondNumber && thirdNumber
. Both are truthy, so this expression will evaluate to 5, the value of secondNumber
. Now our expression is reduces to firstNumber || 5
, we need to evaluate that expression, and since firstNumber
is also truthy (3), the expression returns the first operand, i.e. 3.
The last example can be similarly evaluated. We take secondNumber && thirdNumber
first. Both are truthy, so it returns second operand (thirdNumber
, the value is 7). Now we can move on to the ||
operator by evaluating falsyValue || 7
. The first operand (falsyValue
) is falsy, so the expression will return the second operand, so we’ll get 7.
Changing the order
Can we override the operator precedence? Yes, if we place the “weaker” expression (||
) in parentheses. Memories from math class may indicate that parentheses come first when we decide on the order of numerical operations either.
The same applies here. All we have to do is to put the ||
in parentheses:
console.log(falsyValue && secondNumber || thirdNumber); // 7
console.log(falsyValue && (secondNumber || thirdNumber)); // 0
In the first example, we take falsyValue && secondNumber
first, it returns falsyValue
(0). The problem has been reduced to evaluate 0 || thirdNumber
, and this will return thirdNumber
(7).
In the second example, however, we override the operator precedence, and we need to take secondNumber || thirdNumber
first. Both are truthy, so we’ll get secondNumber
(5) returned. Evaluating falsyValue && 5
will result in the value of the first operand (since it’s falsy), i.e. 0.
Short circuit
The behavior of these operators makes it possible to do the so-called “short-circuit”. Because of the logic of the &&
and ||
operators, whatever the second operand is, the following expressions are always evaluated to false
and true
, respectively:
console.log(false && { name: 'Alice' }); // false
console.log(true || { name: 'Alice' }); // true
We could have written anything instead of Alice’s object, the first expression will always be false
and the second will always be true
.
Conclusion
The &&
and ||
logical operators are important tools in the toolkit of the JavaScript developer. Knowing the subtleties of these operators will help exploit all of their features and write more seamless and elegant code.
Enjoy coding!