JavaScript: Operators
Master every operator in JavaScript: from basic arithmetic to nullish coalescing, optional chaining, spread, and rest.
Arithmetic Operators
Arithmetic operators perform mathematical calculations. JavaScript supports the standard four plus modulo (%) and exponentiation (**) introduced in ES2016.
Arithmetic Operators
Standard math operations, with two worth noting: % gives remainder, ** raises to a power.
- +: addition (also concatenation when a string is involved)
- -: subtraction
- *: multiplication
- /: division (always returns a float:
7 / 2 === 3.5) - %: remainder (modulo):
10 % 3 === 1 - **: exponentiation:
2 ** 8 === 256
Arithmetic Operators
% is useful for checking even/odd; ** replaces Math.pow().
Press Run to execute the code and see output here.
Assignment Operators
Assignment operators store a value in a variable. Compound assignment operators combine an arithmetic operation with assignment, making updates concise.
Assignment Operators
Compound assignments are shorthand: x += 5 means x = x + 5.
- =: basic assignment
- +=: add and assign:
x += 5 - -=: subtract and assign:
x -= 5 - *=: multiply and assign:
x *= 2 - /=: divide and assign:
x /= 2 - %=: modulo and assign:
x %= 3 - **=: exponentiate and assign:
x **= 2
Compound Assignment Operators
Each line updates score in place: run to trace through the chain.
Press Run to execute the code and see output here.
Comparison Operators
Comparison operators evaluate two values and return a boolean. The most important distinction is between loose equality (==) which allows type coercion, and strict equality (===) which does not.
== vs ===
Always use === in production: == can produce unexpected results through coercion.
- ===: strict equality: same value AND same type
- !==: strict inequality: different value OR different type
- ==: loose equality: converts types before comparing
- !=: loose inequality
- >, <, >=, <=: work numerically or lexicographically on strings
Strict vs Loose Equality
5 == "5" is true: 5 === "5" is false. Always use === to avoid coercion surprises.
Press Run to execute the code and see output here.
Logical Operators
Logical operators combine boolean expressions. In JavaScript they also use short-circuit evaluation: they stop as soon as the result is determined and return the actual value that caused the stop, not just true/false.
&&, ||, !
Logical operators short-circuit and return the deciding operand, not always a boolean.
- &&: returns the first falsy value, or the last value if all are truthy
- ||: returns the first truthy value, or the last value if all are falsy
- !: negates a boolean;
!!converts any value to boolean - Short-circuit:
false && heavyFn(): heavyFn is never called
Short-Circuit Evaluation
|| is commonly used for default values, but ?? is safer (see Nullish Coalescing).
Press Run to execute the code and see output here.
Unary Operators
Unary operators act on a single operand. They include increment/decrement, numeric conversion, typeof, and delete.
Unary Operators
Operate on one value: prefix vs postfix placement matters for ++ and --.
- ++ prefix (
++x): increments then returns new value - ++ postfix (
x++): returns current value then increments - +x: converts x to a number:
+"5" === 5 - -x: negates x
- typeof: returns a string type label
- delete: removes a property from an object
Unary Operators
Prefix ++ vs postfix ++ differ in when the return value is read.
Press Run to execute the code and see output here.
Ternary Operator
The ternary operator is the only JavaScript operator that takes three operands. It is a concise inline alternative to an if/else when assigning or returning one of two values.
? : (Ternary)
condition ? valueIfTrue : valueIfFalse: one expression, two possible results.
- Syntax:
condition ? expr1 : expr2 - Best for simple, readable two-branch choices
- Avoid nesting ternaries: use if/else for complex logic
- Can be used inside template literals:
`Hello, ${isAdmin ? "Admin" : "User"}`
Ternary Operator
Great for simple inline choices: switch to if/else when you need more than two branches.
Press Run to execute the code and see output here.
Nullish Coalescing Operator (??)
The nullish coalescing operator (??) returns the right-hand side only when the left is null or undefined. This makes it safer than || for default values when 0 or "" are valid values.
?? vs ||
Use ?? when 0 or empty string are valid values that should not trigger the default.
a ?? b: returns b only if a isnullorundefineda || b: returns b if a is any falsy value (0, "", false, null, undefined)- Use
??for configuration defaults where 0 or "" are legitimate inputs - Can be combined with
??=(nullish assignment):x ??= "default"
?? vs || for Default Values
volume ?? 50 keeps 0; volume || 50 replaces it: a critical difference.
Press Run to execute the code and see output here.
Optional Chaining Operator (?.)
Optional chaining (?.) safely accesses deeply nested properties. If any part of the chain is null or undefined, the whole expression short-circuits to undefined instead of throwing a TypeError.
?. (Optional Chaining)
Access nested properties safely: returns undefined instead of crashing.
obj?.prop: returns undefined if obj is null/undefinedobj?.method(): calls the method only if it existsarr?.[0]: safely accesses an array index- Combine with
??to provide a fallback:user?.name ?? "Guest"
Optional Chaining
?. turns a TypeError crash into a clean undefined: combine with ?? to provide a fallback.
Press Run to execute the code and see output here.
Spread Operator (...)
The spread operator (...) expands an iterable (array, string, or object) into individual elements. It is used for copying, merging, and passing arguments.
Spread (...)
Unpacks an iterable into individual elements at the call site.
- Copy an array:
[...original], shallow clone - Merge arrays:
[...a, ...b] - Copy/merge objects:
{ ...obj, newKey: value } - Pass array as function arguments:
Math.max(...nums)
Spread Operator
Later spread properties overwrite earlier ones: useful for applying overrides on top of defaults.
Press Run to execute the code and see output here.
Rest Operator (...)
The rest operator uses the same ... syntax as spread but does the opposite: it collects multiple values into a single array. It appears in function parameters and destructuring assignments.
Rest (...)
Gathers remaining values into an array: the inverse of spread.
- In function params: collects all extra arguments into an array
- Must be the last parameter:
function fn(a, b, ...rest) - In destructuring:
const [first, ...remaining] = arr - Replaces the old
argumentsobject: rest is a real array with all array methods
Rest Operator
Rest collects; spread expands: same syntax, opposite direction.
Press Run to execute the code and see output here.
Operator Precedence
Operator precedence determines the order in which operators are evaluated when an expression contains multiple operators. Higher precedence operators are evaluated first. Use parentheses to override the default order.
Operator Precedence
When in doubt, add parentheses: they are always evaluated first and make intent clear.
- Highest: Grouping
()→ Member access.→ Function call() - Unary:
!,++,--,typeof - Arithmetic:
**→* / %→+ - - Comparison:
< > <= >=→=== !== == != - Logical:
&&→||→?? - Lowest: Assignment
= += -=…
Operator Precedence
Parentheses cost nothing: use them to make complex expressions unambiguous.
Press Run to execute the code and see output here.
| Priority | Operator(s) | Example |
|---|---|---|
| 1 (highest) | Grouping () | (2 + 3) |
| 2 | Member . / ?. | obj.name |
| 3 | Unary ! ++ -- typeof | !flag, ++x |
| 4 | Exponentiation ** | 2 ** 8 |
| 5 | Multiply * / % | 10 * 3 |
| 6 | Add / Subtract + - | 5 + 2 |
| 7 | Comparison < > <= >= | a > b |
| 8 | Equality === !== | a === b |
| 9 | Logical AND && | a && b |
| 10 | Logical OR || | a || b |
| 11 | Nullish ?? | a ?? b |
| 12 (lowest) | Assignment = += -= | x = 5 |
String Concatenation vs Addition
The + operator is overloaded: it performs numeric addition when both operands are numbers, but switches to string concatenation the moment either operand is a string. This is the most common source of accidental coercion bugs.
+ Operator Overloading
+ is the only arithmetic operator that concatenates: all others (- * /) always convert to numbers.
- Number + Number → addition:
5 + 3 → 8 - String + anything → concatenation:
"5" + 3 → "53" - Use
Number()or unary+to force numeric addition - Template literals are cleaner than + for building strings:
`Hello, ${"{name}"}`
+ Concatenation vs Addition
Only + is ambiguous: subtract, multiply, and divide always produce numbers.
Press Run to execute the code and see output here.
Knowledge Check
1. What is the result of 2 ** 10 in JavaScript?
2. What is the difference between == and ===?
3. What does the ?? operator do?
4. What is the result of "5" + 3 in JavaScript?
5. What does optional chaining (?.) do when a property does not exist?
6. What does the rest operator (...) do in a function parameter list?
7. Which of the following correctly uses the ternary operator?
8. What is the result of !!"" (double negation of an empty string)?
9. Which operator has the highest precedence?
10. What does the spread operator do when used with an array?