JavaScript provides us 3 logical operators : and, or and not. They are typically used with Boolean (logical) values. When they are, they return a Boolean value.

However, the && and || operators actually return the value of one of the specified operands, so if these operators are used with non-Boolean values, they will return a non-Boolean value. This is called short-circuit evaluation , as logical expressions are evaluated left to right, they are tested using the following rules:

  • (some falsy expression) && expr is short-circuit evaluated to the falsy expression;
  • (some truthy expression) || expr is short-circuit evaluated to the truthy expression.

Logical and

Returns true if both operands are true:

<expression> && <expression>

For example:

a === true && b > 0

The cool thing about the operator && is that the second expression is never executed if the first evaluates to false. Which has some practical applications, for example, to check if an object is defined before using it:

const car = { brand: 'Toyota' };
const brand = car && car.brand;

console.log(brand);
// expected output: 'Toyota'

or

const car = {};
const brand = car && car.brand;

console.log(brand);
// expected output: undefined

Logical or

Returns true if at least one of the operands is true:

<expression> || <expression>

For example:

a === true || b > 0

This operator is very useful to fallback to a default value. For example:

const car = {};
const brand = car.brand || 'Ford';

console.log(brand);
// expected output: Ford

makes the brand default to Ford if car.brand is not defined.

Logical not (!)

Invert the value of a boolean, returns false if its single operand can be converted to true; otherwise, returns true.

If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

null;
NaN;
0;
"";
'';
``;
undefined;
let value = true;

console.log(!value);
// expected output: false

value = 'test';

console.log(!value);
// expected output: false
let value = false;

console.log(!value);
// expected output: true

value = '';

console.log(!value);
// expected output: true

value = null;

console.log(!value);
// expected output: true

// or any falsy value