FundamentalsChapter 15 of 21
Logical
Combining conditions, and using and, or and nullish for defaults.
and, or, not
JavaScript
const age = 20;
const hasTicket = true;
console.log(age >= 18 && hasTicket);
console.log(age < 18 || hasTicket);
console.log(!hasTicket);Output
true true false
They return values, not booleans
This is the part worth understanding. && and || do not produce true or false: they produce one of the operands.
JavaScript
console.log('a' && 'b');
console.log('' && 'b');
console.log('' || 'fallback');
console.log('set' || 'fallback');Output
b fallback set
&& returns the first falsy value, or the last one if none are falsy. || returns the first truthy value, or the last one if none are truthy.
Short circuiting
Both stop as soon as the answer is known, so the right side may never run. That is useful and occasionally surprising.
JavaScript
function shout() {
console.log('this ran');
return true;
}
false && shout();
true || shout();
console.log('nothing above printed');Output
nothing above printed
It is also how a guard is written: user && user.name never touches name when user is missing.
Nullish coalescing
?? looks like || but only steps in for null and undefined. That difference matters whenever zero or an empty string is a real answer.
JavaScript
const count = 0;
console.log(count || 10);
console.log(count ?? 10);Output
10 0
Gotcha
Defaults written with || quietly replace 0, "" and false. If those are valid values, use ??.
Combining them
&& binds tighter than ||, and mixing ?? with either without brackets is a syntax error, which the language does on purpose to stop ambiguous code.
JavaScript
const isAdmin = false;
const isOwner = true;
const isBanned = false;
console.log((isAdmin || isOwner) && !isBanned);Output
true
Test yourself
2 questionsWhat does the expression 0 || 10 produce?
Show the answer
10 0 is falsy, so || moves on to the next value. Use ?? when 0 should be kept.
What does && return?
Show the answer
The first falsy operand, or the last one Which is what makes user && user.name a useful guard rather than just a test.
Data Types
The eight types, and the line between primitives and objects.