Skip to main content
๐Ÿงฑbeginner

Operators

Master arithmetic, comparison, logical, and nullish operators โ€” the tools that let you manipulate and combine values.

Arithmetic Operators

The basic math operators you know, plus a few extras:

hljs javascript
console.log(10 + 4);   // 14
console.log(10 - 4);   // 6
console.log(10 * 4);   // 40
console.log(10 / 4);   // 2.5
console.log(10 % 4);   // 2  (remainder/modulo)
console.log(2 ** 8);   // 256 (exponentiation, ES7)

let x = 5;
x++;  // increment: x is now 6
x--;  // decrement: x is now 5
x += 10; // x = x + 10 โ†’ 15
x -= 3;  // x = x - 3  โ†’ 12
x *= 2;  // x = x * 2  โ†’ 24
x /= 4;  // x = x / 4  โ†’ 6

Pre vs post increment:

hljs javascript
let a = 5;
console.log(a++); // 5 โ€” returns value THEN increments
console.log(a);   // 6

let b = 5;
console.log(++b); // 6 โ€” increments THEN returns value
console.log(b);   // 6

Comparison Operators

Comparisons return a boolean (true or false):

hljs javascript
console.log(5 > 3);    // true
console.log(5 < 3);    // false
console.log(5 >= 5);   // true
console.log(5 <= 4);   // false
console.log(5 === 5);  // true  (strict equality)
console.log(5 !== 3);  // true  (strict inequality)

Always use === and !== (strict equality). The loose versions (==, !=) coerce types:

hljs javascript
5 == "5"   // true  โ€” coerces string to number
5 === "5"  // false โ€” no coercion, different types

null == undefined  // true  โ€” surprising!
null === undefined // false โ€” correct

Logical Operators

hljs javascript
// AND: both must be true
true && true   // true
true && false  // false

// OR: at least one must be true
true || false  // true
false || false // false

// NOT: inverts the boolean
!true   // false
!false  // true
!!true  // true (double negation = convert to boolean)

Short-circuit Evaluation

&& and || don't just work with booleans โ€” they short-circuit and return one of their operands:

hljs javascript
// && returns first falsy value, or last value if all truthy
console.log(1 && 2 && 3);   // 3
console.log(1 && 0 && 3);   // 0 (stops at 0)
console.log(false && "hi"); // false

// || returns first truthy value, or last value if all falsy
console.log(0 || "" || "default"); // "default"
console.log(null || undefined || 42); // 42
console.log("hello" || "world");   // "hello"

This is used constantly for default values:

hljs javascript
function greet(name) {
  const displayName = name || "Guest";
  console.log("Hello, " + displayName + "!");
}

greet("Alice"); // Hello, Alice!
greet();        // Hello, Guest!

Nullish Coalescing (??)

?? is like || but only falls back for null and undefined โ€” not 0, "", or false:

hljs javascript
const count = 0;

// || problem: 0 is falsy, so it falls through
console.log(count || "no data"); // "no data" โ€” wrong!

// ?? only checks null/undefined
console.log(count ?? "no data"); // 0 โ€” correct!

const config = {
  timeout: 0,      // intentionally 0
  retries: null,   // not set
};
console.log(config.timeout ?? 3000);  // 0 โœ“
console.log(config.retries ?? 3);     // 3 โœ“

Optional Chaining (?.)

Access nested properties safely without checking each level manually:

hljs javascript
const user = {
  profile: {
    address: {
      city: "New York"
    }
  }
};

// Without optional chaining
const city1 = user && user.profile && user.profile.address && user.profile.address.city;

// With optional chaining โ€” much cleaner
const city2 = user?.profile?.address?.city;
console.log(city2); // "New York"

const noUser = null;
console.log(noUser?.profile?.city); // undefined (no error!)

// Works with methods too
const arr = null;
console.log(arr?.length); // undefined
console.log(arr?.map(x => x)); // undefined

Ternary Operator

A compact if-else expression:

hljs javascript
const age = 20;
const status = age >= 18 ? "adult" : "minor";
console.log(status); // "adult"

// vs the equivalent if-else
let status2;
if (age >= 18) {
  status2 = "adult";
} else {
  status2 = "minor";
}

โœ…Tip

Ternaries are great for simple inline conditions. For complex logic with multiple branches, a regular if-else is more readable.

Spread Operator (...)

Spread expands an iterable (array, string) or object into individual elements:

hljs javascript
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]

// Copy an array
const copy = [...arr1];

// Spread into function arguments
const nums = [10, 20, 30];
console.log(Math.max(...nums)); // 30

// Spread objects
const base = { a: 1, b: 2 };
const extended = { ...base, c: 3, b: 99 }; // b is overridden
console.log(extended); // { a: 1, b: 99, c: 3 }

typeof and instanceof

hljs javascript
typeof "hello"  // "string"
typeof 42       // "number"
typeof {}       // "object"
typeof []       // "object"

// instanceof checks prototype chain
[] instanceof Array  // true
[] instanceof Object // true (arrays are objects)
{} instanceof Object // true

class Dog {}
const rex = new Dog();
rex instanceof Dog    // true
rex instanceof Object // true
โ–ถTry it yourself

Key Takeaways

  • Use === and !== โ€” never == or !=
  • || falls back on any falsy value; ?? only on null/undefined
  • ?. lets you safely navigate nested properties
  • && short-circuits on the first falsy value
  • The spread operator ... copies/merges arrays and objects

Ready to test your knowledge?

Take a quiz on what you just learned.

Take the Quiz โ†’