Blog Cover

JavaScript expressions and operators handbook

Author profile image
Aitor Alonso

Oct 27, 2022

7 min read

JavaScript (and therefore, also Node and TypeScript) has a lot of valid operators and expressions that can be overwhelming to learn, specially for newcomers. I will try to sum them all here in a handy and concise way, so this article can be used as a reference for the future, for both experienced and new developers. Be sure that by understanding them, won't be unrealizable task out there for you.

What are expressions and operators?

First what it's first. Let me write down a few paragraphs for the less experienced, that you can ignore if ou already know the difference between those.

As Mozilla writes in their MDN web docs:

At a high level, an expression is a valid unit of code that resolves to a value.

Okay, so now we know what and expression is. But what about operators? To explain that, first you must know that there are two types of expressions: those that have side effects (such as assigning values) and those that purely evaluate. Let's take a look.

  • Side effects expressions: a = 1. Here, we are using the = operator to assign the value 1 to the variable a. This is a side effect expression, because it changes the value of the variable a. This expression itself evaluates to the value 1.

  • Purely evaluate expressions: a + 1. This expressions uses the + operator to add the value 1 to the variable a. This is a purely evaluate expression, because it doesn't change the value of the variable a, nor generates any change in our code or program. If a equals 1 from our previous example, this expression is equal to doing 1 + 1 and evaluates itself to the value 2.

All complex expressions are joined by operators, such as = and +. JavaScript has a lot of operators, that can be classified into multiple categories.

Types of JavaScript operators

There are different types of operators in JavaScript, and I will explain most of them here with examples. However, if you are looking for an specific operator that you don't know it's name or want to learn further details, you can use the marvelous operator lookup tool that Josh Comeau created in his site. Let's go!

Assignment operators

An assignment operator assigns a value to its left operand based on the value of its right operand. The simple assignment operator, as you can imagine, is equal (=), but there are also compound assignment operators that are shorthand for some operations. For example:

let x = 1 // x is now 1
x += 2 // equals to x + 2. x is now 3
x -= 1 // equals to x - 1. x is now 2
x *= 2 // equals to x * 2. x is now 4
x /= 2 // equals to x / 2. x is now 2

This not only work for arithmetical operations (including %= and **=), but also for bitwise operations (<<=, >>=, >>>=, etc), and boolean operations (&&=, ||=, ??=). Don't worry, we will review these type of operations (and their operators) in detail later.

Comparison operators

A comparison operator compares its operands and returns a logical value based on whether the comparison is true.

const a = 3
const b = 5
a === b // ia a equal to b? false
a !== b // ia a not equal to b? true
a < b // ia a less than b? true
a > b // ia a greater than b? false
a <= b // ia a less or equal than b? true
a >= b // ia a greater or equal than b? false

A note here. If you know about other programming languages, you may notice that JavaScript has a different way of comparing values. In JavaScript, the == and != operators are not the same as === and !==. The first ones are called loose equality and loose inequality, and they are used to compare values that are not of the same type. For example:

const a = 3
const b = '3'
a == b // true
a === b // false

In general, when programming with JavaScript or TypeScript, it's considered a good practice to always use the strict equality operators (=== and !==), unless you especifically want to compare values that are not of the same type.

Arithmetic operators

An arithmetic operator takes numerical values (either literals or variables) as their operands and returns a single numerical value. The standard arithmetic operators are addition (+), subtraction (-), multiplication (*), and division (/), that are common in most programming languages. However, JavaScript also provided additional arithmetic operators such as the remainder (%) and the exponentiation (**) operators, and also the increment (++) and decrement (--) operators.

let a = 2 ** 3 // 2 to the power of 3: (2 * 2 * 2) = 8
let b = 5 % 2 // 5 divided by 2, with the remainder: 1 (b equals 1)
a++ // a is now 9
b-- // b is now 0

Bitwise operators

Bitwise operators treat their operands as a set of 32 bits (zeros and ones in two's complement representation), perform their operations on such binary representations, and return standard JavaScript numerical values. For example:

const a = 3 // 00000000000000000000000000000011
const b = 5 // 00000000000000000000000000000101
a & b // 00000000000000000000000000000001 (equals 1)
a | b // 00000000000000000000000000000111 (equals 7)
a ^ b // 00000000000000000000000000000110 (equals 6)
~a // 11111111111111111111111111111100 (equals -4)

There are a subclass of bitwise operators that are used to shift the bits of their first operand the specified number of places to the left or right. For example:

const a = -5 // 11111111111111111111111111111011
a << 1 // move bits 1 position to left, add zeros, 11111111111111111111111111110110 (equals -10)
a >> 2 // move bits 2 positions to right, 11111111111111111111111111111110 (equals -2)
a >>> 2 // move bits 2 positions to right, add zeros, 00111111111111111111111111111110 (equals 1073741822)

Logical operators

Logical operators are typically used with Boolean (logical) values, like in many other programming languages.

const a = true
const b = false
a && b // false
a || b // true
!a // false

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 may return a non-Boolean value.

0 && 4 // 0, since it's the first falsy value
2 && 4 // 4, since neither value is falsy
1 && 2 && 3 // 3, since all values are truthy
'a' && '' && 0 // '', the first falsy value

0 || 4 // 4, since it's the first truthy value
2 || 4 // 2, since it's the first truthy value
'' || 0 // 0, since no values are truthy
'a' || 2 || 3 // a, since it found a truthy value right away!

JavaScript unique operators

JavaScript has some unique operators that are not present in other programming languages. These are the ternary operator (?), and the nullish coalescing operator (??), and the optional chaining operator (?.).

Conditional (ternary) operator

The ternary operator is unique to Javascript in that it requires two separate pseudo-operators, ? and :.

It's used to evaluate a condition, and return a different value depending on whether that condition is truthy (returns the first value) or falsy (returns the second one). It's functionally equivalent to an if/else statement, but because it's an operator, it's usable in an expression. This allows it to be useful in a broader range of situations (eg. within JSX in React).

console.log(10 ? 'yes' : 'no') // 'yes', since 10 is truthy
console.log(0 ? 'yes' : 'no') // 'no', since 0 is falsy

// Can be used alongside other operators:
console.log(5 < 10 ? 'smaller' : 'larger') // 'smaller'

Nullish coalescing operator

This operator is similar to the Logical OR operator (||), except instead of relying on truthy/falsy values, it relies on "nullish" values (there are only 2 nullish values, null and undefined).

This means it's safer to use when you treat falsy values like 0 as valid.

Similar to Logical OR, it functions as a control-flow operator; it evaluates to the first not-nullish value.

const a = null
const b = undefined
const c = 0
const d = true
a ?? b ?? c ?? d // 0, since 'a' and ' b' are nullish, but 'c' is not

Optional chaining operator

This one is one of my favorites. This operator is similar to the property accessor operator (.), it accesses a property on an object.

The difference is that i is safe to chain; if at any point, a nullish value (null or undefined) is surfaced, it stops evaluating the expression and returns undefined, avoiding some TypeError.

It will be easier to understand with a example:

const a = {}
a.b.c.d // Uncaught TypeError: Cannot read property 'c' of undefined
a?.b?.c?.d // undefined, since 'a' is an empty object, and 'b' is undefined

Conclusions

As you could see, there are plenty of operators in JavaScript, and they can be used in a variety of ways. Here are not all the possible operators, but the most common ones. If you want to learn more about them, you can check the MDN documentation or the above mentioned operator lookup tool from Josh Comeau.

Happy coding!


I hope my article has helped you, or at least, that you have enjoyed reading it. I do this for fun and I don't need money to keep the blog running. However, if you'd like to show your gratitude, you can pay for my next coffee(s) with a one-time donation of just $1.00. Thank you!