Complete JavaScript Course Module 3: Beginner: Making Decisions with Conditions

Logical Operators and the Ternary Operator

  • Beginner
  • Lesson 3.2
  • 5 min read
  • 12 of 76 in the course

In short

JavaScript logical operators (&&, || and !) combine conditions, and the ternary operator writes short if/else choices. You will also learn default values with || and ??. The three logical operators: &&, || and ! Often one condition isn't enough.

JavaScript logical operators (&&, || and !) combine conditions, and the ternary operator writes short if/else choices. You will also learn default values with || and ??.

The three logical operators: &&, || and !

Often one condition isn't enough. "You can rent a car if you are 21 or older and you have a license." Logical operators let you combine conditions:

OperatorNameGives true when...Example
&&ANDboth sides are trueage >= 21 && hasLicense
||ORat least one side is trueisWeekend || isHoliday
!NOTthe value is false (it flips it)!isLoggedIn
const age = 25;
const hasLicense = true;
const isWeekend = false;
const isHoliday = true;
const isLoggedIn = false;

console.log(age >= 21 && hasLicense);   // Output: true
console.log(isWeekend || isHoliday);    // Output: true
console.log(!isLoggedIn);               // Output: true
console.log(!true);                     // Output: false

With &&, everything must be true. With ||, one true is enough. ! turns true into false and false into true.

Combining conditions in if statements

Logical operators are most useful inside if statements. They often replace nested ifs with one clear line.

const username = 'lena_dev';
const password = 'sunflower2026';
const acceptedTerms = true;

if (username !== '' && password.length >= 8 && acceptedTerms) {
  console.log('Account created!');
} else {
  console.log('Please fill in all fields and accept the terms.');
}
// Output: Account created!

const day = 'Saturday';
if (day === 'Saturday' || day === 'Sunday') {
  console.log('The store opens at 10:00.');
} else {
  console.log('The store opens at 8:00.');
}
// Output: The store opens at 10:00.

The signup check needs three things to be true at once, so it uses &&. The store hours depend on either of two days, so it uses ||.

When you mix && and ||, && is calculated first, like * before +. Use brackets to make your meaning clear: (isMember || hasCoupon) && cartTotal > 20.

Common mistake: Writing day === 'Saturday' || 'Sunday'. This doesn't compare day with 'Sunday'; the string 'Sunday' on its own is just truthy, so the whole condition is always true. Repeat the full comparison on each side.

Short-circuiting: how && and || really work

JavaScript reads && and || from left to right and stops as soon as it knows the answer. This is called short-circuiting.

  • With &&, if the left side is falsy, the answer is already "no", so the right side is never run.
  • With ||, if the left side is truthy, the answer is already "yes", so the right side is skipped.

Also, these operators don't just return true or false. They return one of the two values themselves: the value where JavaScript stopped.

const user = 'Amir';
user && console.log(`Welcome back, ${user}!`);
// Output: Welcome back, Amir!

console.log('Amir' || 'Guest');    // Output: Amir
console.log('' || 'Guest');        // Output: Guest
console.log(0 && 'never checked'); // Output: 0

In the first example, user is truthy, so JavaScript continues and runs the console.log. If user were an empty string, nothing would happen.

Default values with || and ??

Short-circuiting gives a handy trick for default values: "use this value, or a backup if it's missing".

const savedName = '';
const displayName = savedName || 'Guest';
console.log(displayName);
// Output: Guest

But || replaces every falsy value, including 0 and ''. Sometimes those are real, valid values. That's why modern JavaScript also has ??, the nullish coalescing operator. It only uses the backup when the value is null or undefined.

const itemsInCart = 0;   // a real value: the cart is empty
const volume = 0;        // the user muted the sound

console.log(itemsInCart || 'unknown');   // Output: unknown   (wrong, 0 is a real answer)
console.log(itemsInCart ?? 'unknown');   // Output: 0         (correct)

let userTheme = null;
console.log(userTheme ?? 'light');       // Output: light
console.log(volume ?? 50);               // Output: 0
Value on the leftvalue || 'default'value ?? 'default'
'Sara''Sara''Sara'
0'default'0
'''default'''
null'default''default'
undefined'default''default'

Tip: Use ?? when 0, '' or false are valid values. Use || when any empty or falsy value should be replaced.

The ternary operator: a short if/else

The ternary operator is a compact way to choose between two values. It's called "ternary" because it has three parts:

condition ? valueIfTrue : valueIfFalse

Read it as a question: "Is the condition true? If yes, use the first value; otherwise, use the second."

const age = 20;
const access = age >= 18 ? 'allowed' : 'denied';
console.log(`Access ${access}`);
// Output: Access allowed

const stock = 0;
console.log(`Status: ${stock > 0 ? 'In stock' : 'Sold out'}`);
// Output: Status: Sold out

const count = 1;
console.log(`You have ${count} new ${count === 1 ? 'message' : 'messages'}`);
// Output: You have 1 new message

The ternary is perfect when you need to pick one of two values, especially inside a template literal. For running different actions (several lines of code), a normal if/else is clearer.

When not to nest ternary operators

You can put a ternary inside another ternary, but it quickly becomes hard to read:

const score = 75;

// Hard to read: avoid this
const resultBad = score >= 90 ? 'Excellent' : score >= 60 ? 'Pass' : 'Fail';

// Clear: use if/else if for three or more options
let result;
if (score >= 90) {
  result = 'Excellent';
} else if (score >= 60) {
  result = 'Pass';
} else {
  result = 'Fail';
}

console.log(resultBad, result);
// Output: Pass Pass

Both give the same answer, but the second version is much easier to read and change. A good rule: one ternary is fine; for more than two options, use if/else.

Practice exercise

Write a "free delivery" check. Create const cartTotal, const isMember and const promoCode (set it to null). Delivery is free if the cart total is 50 or more or the customer is a member. Use a ternary to log Delivery: free or Delivery: $4.99. Then log the promo code with a default of 'none' using ??.

Hint: the condition is cartTotal >= 50 || isMember. Try it with different values to test both results.

Key takeaways

  • && needs both sides to be true, || needs at least one, and ! flips true and false.
  • && and || short-circuit: they stop as soon as the answer is known and return one of the values.
  • || replaces any falsy value; ?? replaces only null and undefined.
  • The ternary condition ? a : b picks one of two values in a single line.
  • Don't nest ternaries; use if/else for three or more options.