Topic 2.1
Operators
In one line
Operators are the symbols that combine values into new values: + - * / % ** for maths, = and += to store results, ++ and -- to count, < > <= >= to compare, and + again to join strings, all evaluated in a fixed order called precedence.
Think of it like this
A calculator. The numbers you type are the values, and the buttons +, −, × and ÷ are the operators: each one takes the numbers next to it and produces a new number. A good calculator also knows that 2 + 3 × 4 is 14, not 20, because multiplication happens first. JavaScript works the same way, with a few extra buttons and a few surprises.
Words you'll meet
New words in this topic, in plain English. Come back here whenever one feels fuzzy.
- Operator
- A symbol like
+,*or<that takes values and produces a new value. - Operand
- A value an operator works on. In
7 + 2, the operands are7and2. - Expression
- Any piece of code that produces a value, like
7 + 2,x, or"hi". - Unary / binary
- A unary operator takes one value (
-x,!x); a binary operator takes two (a + b). - Remainder (%)
- What is left over after dividing:
7 % 2is1. - Concatenation
- Joining strings end to end:
"ab" + "cd"gives"abcd". - Compound assignment
- A shortcut like
x += 5that meansx = x + 5. - Precedence
- The order operators run in when there are several, like
*before+. - Associativity
- Which side goes first when operators have the same precedence: usually left to right.
Step by step
01Do the maths
The arithmetic operators work like school maths, with two additions: % gives the remainder and ** raises to a power. / never throws away the decimal part.
console.log(7 / 2); // 3.5
console.log(7 % 2); // 1 (7 = 3 * 2 + 1)
console.log(2 ** 10); // 1024
console.log(Math.trunc(7 / 2)); // 3, whole-number division02Watch out for + with strings
If either side of + is a string, + joins instead of adding. Values from inputs, URLs and storage are strings, so convert them first with Number(...) (Topic 1.5 — Type Conversion).
const qty = "2"; // from an <input>: always a string
console.log(qty + 3); // "23" joined!
console.log(Number(qty) + 3); // 5 added03Store and update results
= stores a value. Compound operators update in place: total += price reads total, adds price and stores the result back. count++ adds one.
Prefix and postfix only differ when you use the value in the same expression. Keep ++ on its own line and the difference never bites.
let total = 0;
total += 40; // 40
total *= 3; // 120
let count = 0;
count++; // 104Compare values
Comparisons produce booleans, ready for an if (Topic 2.3). Numbers compare by size; strings compare letter by letter by character code; a string against a number becomes a number comparison.
05Let precedence decide the order, or decide it yourself
The engine builds a tree from your expression using the precedence table, then works from the leaves up. Higher-precedence operators sit lower in the tree and run first.
Try it yourself
- 1
Predict the joins
In the second example, add
console.log("3" + 4 + 5, 3 + 4 + "5");. Write your prediction down, then run. (Answer:345 75.) - 2
Fix the quantity
Change the input's
valueto10and run. The red line shows103; the green line shows13. Change the red line's code so both are correct. - 3
Move the parentheses
In the last example, change
2 ** 3 ** 2to(2 ** 3) ** 2. Predict first: is it still 512? (It's64.)
Code & diagrams
`%` keeps the sign of the left number and works on decimals too. Dividing by zero gives `Infinity` or `NaN`, never an error.
Preview
Console
Nothing logged yet.Expected console output
7 + 2 = 9
7 - 2 = 5
7 * 2 = 14
7 / 2 = 3.5
7 % 2 = 1
2 ** 3 = 8
-7 % 2 = -1
5.5 % 2 = 1.5
1 / 0 = Infinity
0 / 0 = NaNOnly `+` joins. `-`, `*`, `/` and unary `+` always convert to numbers. Left-to-right order explains `33` vs `123`.
Preview
Console
Nothing logged yet.Expected console output
string
33
123
3
10
42 0 NaN
2Console
(nothing was printed)Expected console output
score: 8
postfix: 6 5
prefix: 6 6
chained: 0 0`"10" < "9"` compares text letter by letter; `"10" < 9` converts the string to a number first. `-` runs left to right, `**` right to left.
Console
(nothing was printed)Expected console output
true true false
true true false
true false
false false false
14
20
3
512
trueBreak it on purpose
Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.
Break #1
Put a minus sign in front of a power
In the last example, add the line console.log(-2 ** 2); and run.
Break #2
Add up input values without converting
In the second example, add console.log(qty + qty);.
Myth vs fact
Myth
% is the modulo operator from maths.
Fact
It's the remainder: the result has the sign of the left operand, so -7 % 2 is -1, while true modulo gives 1. For an always-positive result use ((n % m) + m) % m.
Myth
7 / 2 gives 3 like in some other languages.
Fact
JavaScript has one number type, so / gives 3.5. Use Math.trunc, Math.floor or Math.round to get a whole number on purpose.
Myth
x++ and ++x are the same.
Fact
Both add one to x. They differ in the value the expression gives back: old value for x++, new value for ++x. That matters as soon as you write y = x++.
Myth
You need to memorise the whole precedence table.
Fact
Know the big ones (* before +, comparisons before &&, assignment last) and use parentheses for everything else. Readable code beats clever code.
Pro corner
Extra depth for experienced readers. New to this? Skip it for now and come back later.
- ▸
Under the hood,
+follows the spec's ApplyStringOrNumericBinaryOperator: both sides are first converted with ToPrimitive (objects callvalueOf/toString), and if either result is a string, it concatenates. That's why[1] + [2]is"12"and{} + []behaves differently at the start of a line (where{}is read as an empty block). - ▸
Comparisons with
nullandundefinedare inconsistent by design:null >= 0istrue(relational operators convertnullto0) whilenull == 0isfalse(loose equality has its own rules).undefinedbecomesNaN, so every relational comparison with it isfalse. Check for missing values explicitly before comparing. - ▸
String comparison with
<uses UTF-16 code units, not language rules. To sort or compare words for humans (accents, case, numbers inside text) usea.localeCompare(b)orIntl.Collator(you'll meet these with sorting in Phase 5). - ▸
V8 stores small whole numbers as Smis (small integers) and switches to doubles when a result has a decimal or overflows. Keeping arithmetic in whole numbers in hot loops (for example, cents instead of decimal rupees) avoids both rounding errors and that switch.
Remember this
- 1
An operator is a symbol (or keyword) that takes one or more values and produces a new value. The values it works on are called operands. In
7 + 2, the operator is+and the operands are7and2. An operator with two operands is binary (a * b); one with a single operand is unary (-a,!a,typeof a). A piece of code that produces a value, like7 + 2or just7, is called an expression. - 2
Arithmetic operators:
+add,-subtract,*multiply,/divide,%remainder and**exponent (power,since ES2016). Division always gives a decimal if needed:7 / 2is3.5, never3(there is no separate whole-number division; useMath.trunc(7 / 2)for that).%gives what is left over:7 % 2is1, which is how you test even and odd numbers. Its result takes the sign of the left number, so-7 % 2is-1: it is a remainder, not the mathematical modulo. Dividing by zero doesn't crash:1 / 0isInfinityand0 / 0isNaN(see Topic 1.3 — Numbers in Depth). - 3
+has two jobs. If either operand is a string, it joins (concatenates) them into one string:"Hi " + "Asha"is"Hi Asha"and"5" + 2is"52". Only when neither side is a string does it add. All the other arithmetic operators (- * / % **) only do maths, so they convert strings to numbers:"5" - 2is3. Expressions run left to right, so1 + 2 + "3"is"33"(1 + 2 is 3 first, then joined with "3"), while"1" + 2 + 3is"123". The unary plus+valueconverts to a number:+"42"is42. This is the number-one beginner bug with form inputs, whose values are always strings. - 4
Assignment operators store a value in a variable.
=assigns; compound assignment combines an operation with the assignment:x += 5meansx = x + 5, and the same works for-=,*=,/=,%=and**=. An assignment is itself an expression whose value is the assigned value, which is whya = b = 0sets both (it runs right to left). Increment++adds 1 and decrement--subtracts 1. Their position matters when you use the result: postfixx++gives back the old value then adds, prefix++xadds first and gives back the new value. Used alone on a line (count++;) they do the same thing. - 5
Comparison operators
<,>,<=and>=givetrueorfalse. Two numbers compare as numbers. Two strings compare character by character by their UTF-16 code (the number each character has in the Unicode table), so"apple" < "banana"istrue, every capital letter comes before every small one ("Z" < "a"istrue) and"10" < "9"istruebecause"1"comes before"9". If one side is a number and the other a string, the string is converted to a number first, so"10" < 9isfalse. Anything compared withNaNisfalse. (Equality,===and==, was Topic 1.6.) - 6
Precedence is the order in which operators run when an expression has several. From first to last, the ones you'll use most: grouping
( ), unary operators (!,-x,+x,typeof,++,--), then**, then* / %, then+ -, then comparisons< > <= >=, then equality=== !==, then&&, then||and??, then the ternary? :, and assignment last. Operators with the same precedence run left to right (associativity), except**and assignment, which run right to left:2 ** 3 ** 2is2 ** 9, which is512. When in doubt, add parentheses: they cost nothing and make your intent clear to the next reader.
Explain it without notes
Why does "5" + 2 give "52" while "5" - 2 gives 3?
What is the difference between x++ and ++x?
What is operator precedence, and how do you control it?
Why is "10" < "9" true but "10" < 9 false?
Practice
Write a line that prints whether the number n = 17 is even or odd using %.
A shop sells pens at 12 rupees. Read the quantity "4" (a string, as from an input), and print Total: 48.
Without running it, predict what console.log(3 + 4 * 2 ** 2 - 1) prints, then check.
Trade-offs
- ↔
Compact expressions like
total += qty * priceare clear; long one-liners mixing++, assignment and comparisons save lines but hide bugs. Split them into named steps. - ↔
Relying on implicit conversion (
"5" * 2) works but hides intent; explicitNumber()costs a few characters and makes the code obvious.
Done when you can
I can use
+ - * / % **and predict their results, including decimals and division by zero.I can explain when
+joins strings and avoid that bug with form input.I can use
+=,++and--, and explain prefix vs postfix.I can predict string vs number comparisons.
I can work out an expression's order from precedence, and add parentheses to make it clear.