You will be able to combine JavaScript conditions using &&, ||, and ! to write safe, readable checks.
What it is
Logical operators combine boolean expressions. JavaScript’s logical operators are short-circuiting: they evaluate left-to-right and stop as soon as the final result is known. && means “and”, || means “or”, and ! means “not”. Related terms include truthy, falsy, short-circuit evaluation, guard clause, and fallback value.
Falsy values include false, 0, -0, 0n, "", null, undefined, and NaN. Everything else is truthy.
Why it matters
- Prevent runtime errors by checking an object exists before reading properties:
user && user.isActive. - Provide default values:
username || "Guest". - Combine multiple rules in one readable condition:
isSignedIn && hasPermission. - Negate a condition without writing
=== false:!isBlocked. - Keep code concise while preserving short-circuit behavior.
Syntax or steps
Smallest useful pattern:
if (value && value.property) {
// safe to use value.property
}
For fallback:
const result = value || fallback;
For negation:
if (!isBlocked) {
// continue only when isBlocked is falsy
}
Operator precedence is !, then &&, then ||. Use parentheses when the intended grouping is not obvious.
Example
const user = { name: "Ada", isActive: true, role: "editor" };
const guest = null;
function canEdit(user) {
return Boolean(user && user.isActive && user.role === "editor");
}
function displayName(user) {
return (user && user.name) || "Guest";
}
console.log(canEdit(user)); // true
console.log(canEdit(guest)); // false
console.log(displayName(user)); // "Ada"
console.log(displayName(guest)); // "Guest"
Part-by-part:
user && user.isActivefirst checks whetheruseris truthy. If it isnull, evaluation stops and the whole expression is falsy, souser.isActiveis never accessed.&& user.role === "editor"adds another required condition. All three must be truthy forcanEditto returntrue.Boolean(...)converts the short-circuit result to a real boolean instead of returning a value likenullorundefined.(user && user.name) || "Guest"returnsuser.namewhen it is truthy; otherwise it returns"Guest".
Common mistakes
- Assuming
&&and||always return booleans. They return one of the operands. UseBoolean(value)or!!valuewhen you need a boolean. - Using
||for defaults when0,"", orfalseare valid values. Use??if you only want to replacenullorundefined. - Forgetting operator precedence.
!isBlocked && isAdmin || isEditoris hard to read. Add parentheses:(!isBlocked && isAdmin) || isEditor. - Using
&&to guard a property when the left side might be a primitive. Ifuseris a string,user && user.isActivedoes not throw, but it may silently returnundefined. Validate the expected type when needed.
When to use it
Logical operators are best for simple condition combinations and fallbacks. Use a ternary when you need two different result expressions, and use optional chaining when you only need safe property access.
| Pattern | Use when | Example |
|---|---|---|
&& |
All conditions must pass, or stop early on falsy | user && user.isActive |
|| |
Choose first truthy value or fallback | name || "Guest" |
?? |
Fallback only for null or undefined |
count ?? 0 |
| Ternary | Return different values based on a condition | isAdmin ? "admin" : "user" |
Practice
Guided exercise: write isEligible(user) that returns true only when user exists, user.isActive is truthy, and user.age is at least 18.
function isEligible(user) {
return Boolean(user && user.isActive && user.age >= 18);
}
Expected output: isEligible({ isActive: true, age: 20 }) returns true; isEligible(null) returns false.
Challenge: fix this line so that a valid score of 0 is not replaced by "No score": const label = score || "No score";
Solution hint: use score ?? "No score" if only null or undefined should trigger the fallback.
Quick check
Question: What does 0 || "ready" return?
Answer: "ready", because 0 is falsy, so || returns the next operand.
Summary
Logical operators let you combine conditions and choose fallback values with short-circuit evaluation. Use && to require multiple truthy checks, || to pick the first truthy value, and ! to negate a condition. Choose ?? or a ternary when you need more precise control over defaults and branches.