Operators are the symbols that do work on values: adding, comparing, combining conditions. Most behave as you would expect, but a few convert types behind your back. This lesson covers the everyday operators and explains why === should be your default for comparisons.
Arithmetic operators
console.log(7 + 2);
// 9
console.log(7 - 2);
// 5
console.log(7 * 2);
// 14
console.log(7 / 2);
// 3.5
console.log(7 % 2);
// 1
console.log(2 ** 3);
// 8
/always gives a decimal result if needed; there is no separate whole-number division.%is the remainder operator.7 % 2is 1 because 7 divided by 2 leaves 1. It is handy for checking whether a number is even:n % 2 === 0.**raises to a power.
Operators follow the usual maths precedence: *, / and % happen before + and -. Use brackets when in doubt; they make your intent clear to readers too.
console.log(2 + 3 * 4);
// 14
console.log((2 + 3) * 4);
// 20
Assignment operators
= stores a value. The compound operators update a variable using its current value:
let total = 10;
total += 5; // same as total = total + 5
total -= 3; // total = total - 3
total *= 2; // total = total * 2
console.log(total);
// 24
++ and -- add or subtract 1:
let lives = 3;
lives--;
console.log(lives);
// 2
Use them as standalone statements. Writing ++ inside larger expressions is legal but hard to read.
Comparison operators
Comparisons produce a boolean:
console.log(5 > 3);
// true
console.log(5 >= 5);
// true
console.log(2 < 1);
// false
console.log(4 <= 3);
// false
Strings are compared character by character using their Unicode code points, which mostly matches alphabetical order for lowercase letters, but uppercase letters come before all lowercase ones:
console.log("apple" < "banana");
// true
console.log("Zebra" < "apple");
// true
For sorting text people will read, use localeCompare, covered in lesson 6.
Equality: === and ==
JavaScript has two equality operators, and the difference matters.
Strict equality, ===, is true only when both values have the same type and the same value. It never converts anything:
console.log(5 === 5);
// true
console.log("5" === 5);
// false
console.log(true === 1);
// false
Loose equality, ==, converts the values to a common type first if their types differ, then compares:
console.log("5" == 5);
// true
console.log(true == 1);
// true
console.log(0 == "");
// true
console.log(0 == "0");
// true
console.log("" == "0");
// false
The last three lines show the problem. 0 equals "" and 0 equals "0", but "" does not equal "0". Loose equality is not consistent with itself, and the conversion rules are long and hard to remember.
The not-equal operators follow the same pattern: !== is strict, != is loose.
Use === and !== everywhere. If you need to compare values of different types, convert one deliberately first, for example Number(input) === 5. The conversion is then visible in your code instead of hidden in the operator.
null and undefined
Loose equality treats null and undefined as equal to each other and to nothing else:
console.log(null == undefined);
// true
console.log(null === undefined);
// false
console.log(null == 0);
// false
Some developers deliberately write value == null as a short way to check for "null or undefined". It is the one common use of ==. In this course we write it out in full, or use the ?? operator from lesson 25.
NaN is not equal to itself
console.log(NaN === NaN);
// false
NaN is never equal to anything, including another NaN. Use Number.isNaN(value) to test for it.
Type coercion with other operators
Equality is not the only place JavaScript converts types. The + operator is the one that catches people most. If either side is a string, + joins them as text:
console.log(1 + 2);
// 3
console.log("1" + 2);
// 12
console.log(1 + 2 + "3");
// 33
console.log("1" + 2 + 3);
// 123
1 + 2 + "3" evaluates left to right: 1 + 2 is 3, then 3 + "3" is "33".
The other arithmetic operators only work on numbers, so they convert strings to numbers:
console.log("10" - 4);
// 6
console.log("10" * "2");
// 20
console.log("ten" * 2);
// NaN
This bites hardest with form input. Every value you read from a text field is a string, even if the person typed a number:
const quantity = "3"; // as read from an input
console.log(quantity + 1);
// 31
console.log(Number(quantity) + 1);
// 4
Convert input to a number once, as soon as you read it, and the rest of your code can trust it.
Logical operators
The logical operators combine or flip conditions.
&&(AND) is true when both sides are true.||(OR) is true when at least one side is true.!(NOT) flips true to false and false to true.
const age = 25;
const hasTicket = true;
console.log(age >= 18 && hasTicket);
// true
console.log(age < 12 || age >= 65);
// false
console.log(!hasTicket);
// false
Short-circuiting
&& and || stop as soon as they know the answer, and they return one of the original values rather than always true or false.
a || breturnsaifais truthy, otherwiseb.a && breturnsaifais falsy, otherwiseb.
Falsy values are those that count as false in a condition: false, 0, "", null, undefined and NaN (plus -0 and 0n). Everything else is truthy. Lesson 8 covers this in detail.
That makes || useful for fallbacks:
const nickname = "";
const displayName = nickname || "Guest";
console.log(displayName);
// Guest
But be careful: || treats 0 and "" as missing, which is wrong when they are valid values:
const volume = 0;
console.log(volume || 50);
// 50
The ?? operator, covered in lesson 25, only falls back for null and undefined, and fixes this.
&& is often used to do something only when a value exists:
const user = { name: "Ada" };
console.log(user && user.name);
// Ada
Summary
- Arithmetic operators include
%for remainders and**for powers. Use brackets to make precedence clear. - Compound assignment operators such as
+=update a variable from its current value. ===compares type and value with no conversion. Make it, and!==, your default.==converts types first and follows inconsistent rules. Avoid it.+joins strings if either side is a string; other arithmetic operators convert to numbers. Convert input withNumber()as soon as you read it.&&and||short-circuit and return one of their operands.||treats0and""as missing.