Skip to content
Theory · Operators and type conversion · lesson 5 of 14

Logical operators

In everyday speech we join conditions all the time: "if there is a ticket and a passport", "if it rains or snows". A program has three logical operators for this: && ("and"), || ("or") and ! ("not").

Each of them builds an expression: code that has a value, such as a + b, 42 or the call Math.floor(2.5). With the values true and false, the logical operators work as in logic. The expression a && b gives true only when both values are true, and a || b when at least one is. But && and || accept values of any type, and their result is not necessarily a boolean:

JavaScript
console.log(true && false, true || false, !true); // false true false
console.log("Ann" || "guest"); // Ann
console.log("" || "guest"); // guest
console.log(0 && "never"); // 0
console.log(false && true || true); // true

Let's walk through what was printed:

  1. The first line is ordinary logic: false true false.
  2. "Ann" || "guest" returned Ann, the left value itself, not true.
  3. "" || "guest" returned guest: the operator skipped the empty string.
  4. 0 && "never" returned 0, and "never" was never reached.
  5. The last line prints true; we will see why below.

Both operators return one of the two values they stand between.

What && and || return

To choose which value to return, && and || check the left one as if it were a boolean. In this check, exactly eight values are falsy:

  • false;
  • 0, -0 and 0n;
  • the empty string "";
  • null and undefined;
  • NaN.

Minus zero -0 comes, for example, from -1 * 0, and 0n is zero of type bigint: the letter n at the end marks that type. All other values are truthy, for example "guest" and 42.

Each operator chooses its result in its own way:

  • || returns the left value if it is truthy, and the right one otherwise;
  • && returns the left value if it is falsy, and the right one otherwise;
  • ! always gives a boolean: !0 gives true, and !"Ann" gives false.

A handy picture for || is a guest's name badge at the door. If the guest gave a name, the badge shows the name; if not, it shows "guest". And && is like a row of turnstiles: you stop at the first closed one, and that one becomes the result.

If all the turnstiles are open, the result is the last one: 5 && 1 gives 1. That is where the picture ends: a real turnstile only lets you through or not, while && returns the value itself.

First &&, then ||

In one expression && runs before ||, as * runs before +. So the last line of the first program reads as (false && true) || true:

  1. false && true gives false;
  2. false || true gives true.

Parentheses make the order explicit: (a && b) || c. Use them when both operators meet in one expression: it is easier to read that way.

Short circuit

If the left value is enough for the answer, the right one is not even evaluated. This is called short-circuit evaluation. The turnstiles work the same way: if the first one is closed, nobody walks to the second. || stops after a truthy value, and && stops after a falsy one:

JavaScript
function loud() {
    console.log("called");
    return 1;
}

console.log(1 || loud()); // 1
const x = 0 || loud(); // called
console.log(x); // 1

In the line 1 || loud() the function loud does not run: the left side of || already holds the truthy 1. In the line 0 || loud() the left 0 is falsy, so loud runs: it prints called and returns 1, which goes into x.

&& mirrors this: it evaluates the right side only after a truthy left value. Step through the program below and watch when a loud frame appears above the script frame: only then is the right side really evaluated.

LiveShort circuit: when loud() is calledstep 1 of 12 · frames: 1

The left 1 is truthy, so || returns it at once and does not call loud().

The loud frame appears only when the right side is evaluated

Interviewers often ask this: what do && and || return, and will the function on the right be called? The answer: the operator returns one of the two values, and the right side is evaluated only when the left one is not enough for the answer.

The ?? operator

The ?? operator is like ||, but it returns the right value only when the left one is null or undefined. It is called the nullish coalescing operator. On the guest's badge it writes "guest" only if the name field is missing altogether. The values 0, "" and false are neither null nor undefined, so ?? keeps them:

JavaScript
console.log(0 || 10, 0 ?? 10); // 10 0
console.log(null ?? 10, undefined ?? 10); // 10 10
console.log(false ?? true); // false

Line by line:

  1. 0 || 10 gives 10, because 0 is falsy, while 0 ?? 10 keeps 0.
  2. ?? replaces null and undefined with 10.
  3. false ?? true gives false: it is a real value, not a missing one.

Mixing ?? with || or && without parentheses is not allowed: such a line is a syntax error. With parentheses it works: (a || b) ?? c.

Common mistake

A default value is set with ||, although 0 is a valid value:

JavaScript
const volume = 0;
const shown = volume || 50; // ✗
console.log(shown); // 50

The volume 0 is falsy, so || replaced it with 50. When only a missing value should be replaced, write volume ?? 50: the result is 0.

Key points

  • || returns the left value if it is truthy, otherwise the right one; && returns the left value if it is falsy, otherwise the right one.
  • The right side is evaluated only when the left one is not enough for the answer: this is short circuit.
  • && runs before ||, and ?? mixes with them only through parentheses.
  • ?? replaces only null and undefined, while || replaces any falsy value, even 0 and "".

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way