JavaScript operators produce values under defined coercion, precedence, short-circuit, numeric, assignment, and property rules. Reliable expressions make conversions and grouping explicit instead of relying on visual intuition.
Choose comparison and numeric semantics from the domain, keep side effects visible, distinguish nullish from falsy values, and validate records beyond property operators.
Operators are symbols or keywords that perform operations on values. The values used with operators are called operands. For example, in 10 + 5, the + symbol is the operator, and 10 and 5 are operands.
JavaScript operators are used for arithmetic, assignment, comparison, logic, strings, objects, arrays, type checking, and more. Understanding them is essential before learning conditions, loops, functions, and DOM programming.
Arithmetic operators perform mathematical calculations on numbers. JavaScript also uses + for string concatenation, so the result depends on the operand types.
| Operator | Name | Example | Result |
|---|---|---|---|
| + | Addition | 10 + 3 | 13 |
| - | Subtraction | 10 - 3 | 7 |
| * | Multiplication | 10 * 3 | 30 |
| / | Division | 10 / 3 | 3.333... |
| % | Remainder | 10 % 3 | 1 |
| ** | Exponentiation | 2 ** 3 | 8 |
| ++ | Increment | x++ | Adds 1 |
| -- | Decrement | x-- | Subtracts 1 |
let a = 10;
let b = 3;
console.log(a + b); // 13
console.log(a - b); // 7
console.log(a * b); // 30
console.log(a / b); // 3.3333333333333335
console.log(a % b); // 1
console.log(a ** b); // 1000
let count = 5;
count++;
console.log(count); // 6
count--;
console.log(count); // 5
The increment and decrement operators can be used before or after a variable. Prefix form updates first and then returns the new value. Postfix form returns the old value first and then updates.
let x = 5;
console.log(++x); // 6: increase first, then use value
console.log(x); // 6
let y = 5;
console.log(y++); // 5: use value first, then increase
console.log(y); // 6
Assignment operators store values in variables. Compound assignment operators update a variable using its current value.
| Operator | Meaning | Same As |
|---|---|---|
| = | Assign | x = 10 |
| += | Add and assign | x = x + 5 |
| -= | Subtract and assign | x = x - 5 |
| *= | Multiply and assign | x = x * 5 |
| /= | Divide and assign | x = x / 5 |
| %= | Remainder and assign | x = x % 5 |
| **= | Power and assign | x = x ** 2 |
let total = 10;
total += 5; // 15
total -= 3; // 12
total *= 2; // 24
total /= 4; // 6
total %= 4; // 2
total **= 3; // 8
console.log(total);
Comparison operators compare two values and return a boolean result: true or false. They are commonly used in if statements, loops, filters, and validations.
| Operator | Name | Example | Result |
|---|---|---|---|
| == | Loose equality | 5 == "5" | true |
| === | Strict equality | 5 === "5" | false |
| != | Loose not equal | 5 != "5" | false |
| !== | Strict not equal | 5 !== "5" | true |
| > | Greater than | 10 > 5 | true |
| >= | Greater than or equal | 10 >= 10 | true |
| < | Less than | 3 < 5 | true |
| <= | Less than or equal | 3 <= 2 | false |
console.log(5 == "5"); // true: JavaScript converts the string to number
console.log(5 === "5"); // false: number and string are different types
console.log(false == 0); // true
console.log(false === 0); // false
console.log(10 > 5); // true
console.log(10 >= 10); // true
console.log(3 < 2); // false
Logical operators combine or reverse boolean expressions. JavaScript also uses short-circuit evaluation, which means it may stop evaluating as soon as the final result is known.
| Operator | Name | Returns true when |
|---|---|---|
| && | Logical AND | Both values are truthy |
| || | Logical OR | At least one value is truthy |
| ! | Logical NOT | Reverses truthiness |
const isLoggedIn = true;
const isAdmin = false;
console.log(isLoggedIn && isAdmin); // false
console.log(isLoggedIn || isAdmin); // true
console.log(!isLoggedIn); // false
// Short-circuit example
isLoggedIn && console.log("Welcome back!");
const username = "";
const displayName = username || "Guest";
console.log(displayName); // Guest
Logical operators depend on truthiness. A value does not need to be exactly true or false; JavaScript can treat it as truthy or falsy in boolean contexts.
| Falsy Values | Truthy Values |
|---|---|
| false | Non-empty strings such as "hello" |
| 0, -0, 0n | Non-zero numbers such as 10 |
| "" | Arrays, even empty arrays [] |
| null | Objects, even empty objects {} |
| undefined | Functions |
| NaN | Dates, maps, sets, and most created values |
The + operator joins strings when at least one operand is a string. This is called concatenation. Modern JavaScript often uses template literals because they are easier to read.
const firstName = "Ada";
const lastName = "Lovelace";
console.log(firstName + " " + lastName); // Ada Lovelace
let message = "Hello";
message += ", JavaScript!";
console.log(message); // Hello, JavaScript!
const age = 28;
console.log("Age: " + age); // Age: 28
console.log(`Age: ${age}`); // Age: 28
The ternary operator is a short form of an if...else expression. It is useful when choosing between two values.
const age = 19;
const status = age >= 18 ? "Adult" : "Minor";
console.log(status); // Adult
const score = 72;
const result = score >= 40 ? "Pass" : "Fail";
console.log(result); // Pass
The nullish coalescing operator ?? returns the right-side value only when the left-side value is null or undefined. It is safer than || when values like 0, false, or an empty string are valid.
const savedVolume = 0;
const volumeWithOr = savedVolume || 50;
console.log(volumeWithOr); // 50: not what we wanted
const volumeWithNullish = savedVolume ?? 50;
console.log(volumeWithNullish); // 0: correct
const username = null;
console.log(username ?? "Guest"); // Guest
The optional chaining operator ?. safely accesses nested properties or methods. If the value before ?. is null or undefined, JavaScript returns undefined instead of throwing an error.
const user = {
name: "Maya",
profile: {
email: "maya@example.com"
}
};
console.log(user.profile?.email); // maya@example.com
console.log(user.address?.city); // undefined
const onSave = null;
onSave?.(); // no error
Logical assignment operators combine logical checks with assignment. They are useful for setting defaults or updating values only under specific conditions.
| Operator | Assigns when | Example |
|---|---|---|
| ||= | Current value is falsy | x ||= 10 |
| &&= | Current value is truthy | x &&= 10 |
| ??= | Current value is null or undefined | x ??= 10 |
let title = "";
title ||= "Untitled";
console.log(title); // Untitled
let token = "abc123";
token &&= "hidden";
console.log(token); // hidden
let limit = 0;
limit ??= 10;
console.log(limit); // 0
The ... syntax can be used as spread or rest depending on where it appears. Spread expands values. Rest collects values.
// Spread: expands an array
const numbers = [1, 2, 3];
const moreNumbers = [...numbers, 4, 5];
console.log(moreNumbers); // [1, 2, 3, 4, 5]
// Spread: copies object properties
const user = { name: "Asha", role: "student" };
const updatedUser = { ...user, active: true };
console.log(updatedUser);
// Rest: collects remaining function arguments
function sum(...values) {
return values.reduce((total, value) => total + value, 0);
}
console.log(sum(10, 20, 30)); // 60
Destructuring is a special assignment syntax that extracts values from arrays or objects into variables.
const colors = ["red", "green", "blue"];
const [firstColor, secondColor] = colors;
console.log(firstColor); // red
console.log(secondColor); // green
const product = {
name: "Laptop",
price: 65000
};
const { name, price } = product;
console.log(name); // Laptop
console.log(price); // 65000
JavaScript provides operators for checking types and object relationships. The most common are typeof, instanceof, in, and delete.
| Operator | Purpose | Example |
|---|---|---|
| typeof | Returns the type as a string | typeof 42 |
| instanceof | Checks object prototype relationship | [] instanceof Array |
| in | Checks whether a property exists | "name" in user |
| delete | Deletes an object property | delete user.age |
console.log(typeof "hello"); // string
console.log(typeof 42); // number
console.log(typeof null); // object: historical JavaScript behavior
console.log([] instanceof Array); // true
const user = { name: "Riya", age: 22 };
console.log("name" in user); // true
delete user.age;
console.log(user); // { name: "Riya" }
Bitwise operators work on 32-bit integer representations of numbers. They are less common in everyday web development but useful in flags, permissions, low-level algorithms, and performance-sensitive logic.
| Operator | Name | Example |
|---|---|---|
| & | Bitwise AND | 5 & 1 |
| | | Bitwise OR | 5 | 1 |
| ^ | Bitwise XOR | 5 ^ 1 |
| ~ | Bitwise NOT | ~5 |
| << | Left shift | 5 << 1 |
| >> | Signed right shift | 5 >> 1 |
| >>> | Unsigned right shift | 5 >>> 1 |
Operator precedence decides which operation runs first. Multiplication runs before addition, comparisons run before logical operators, and parentheses can be used to make the order clear.
console.log(2 + 3 * 4); // 14
console.log((2 + 3) * 4); // 20
const age = 20;
const hasId = true;
const canEnter = age >= 18 && hasId;
console.log(canEnter); // true
This example combines arithmetic, comparison, logical, ternary, nullish coalescing, optional chaining, and assignment operators in a simple shopping cart calculation.
const cart = {
item: "Keyboard",
price: 1200,
quantity: 2,
coupon: null,
customer: {
name: "Neha",
isMember: true
}
};
let subtotal = cart.price * cart.quantity;
const discount = cart.coupon ?? 0;
subtotal -= discount;
const deliveryCharge = subtotal >= 2000 ? 0 : 100;
const memberBonus = cart.customer?.isMember && subtotal > 1000;
const total = subtotal + deliveryCharge;
console.log(`Customer: ${cart.customer?.name ?? "Guest"}`);
console.log(`Item: ${cart.item}`);
console.log(`Subtotal: ${subtotal}`);
console.log(`Delivery: ${deliveryCharge}`);
console.log(`Member bonus: ${memberBonus}`);
console.log(`Total: ${total}`);
Operators can convert operands before producing a result. Addition concatenates when string conversion applies, while subtraction and most arithmetic request numeric conversion. Convert external strings deliberately with a parser appropriate to the domain instead of relying on one operator to validate input.
Use strict equality by default. Loose equality has a defined coercion algorithm and is occasionally useful for an intentional nullish check, but broad use makes mixed-type data harder to reason about. `Object.is` differs for NaN and signed zero, while SameValueZero semantics used by Set, Map, and includes treat NaN as equal to itself.
Relational comparison can be numeric or lexicographic depending on converted primitives. Locale-aware human text ordering belongs to `Intl.Collator`, not `<`. Date, decimal, currency, and version strings need domain-aware normalization before comparison.
Truthiness is a control-flow conversion, not domain validation. Zero, empty string, false, NaN, null, and undefined are falsy but can mean different things. Use explicit predicates when missing, empty, disabled, and zero require different behavior.
Precedence determines grouping, while associativity resolves operators at the same precedence. Evaluation of operands can still occur in a different practical order than a reader assumes. Add parentheses when an expression combines arithmetic, comparison, logical operators, assignment, or function calls with side effects.
`&&` returns the first falsy operand or final operand; `||` returns the first truthy operand; `??` returns the right operand only when the left is null or undefined. These operators return values, not normalized booleans. Use `Boolean(value)` when the API contract requires a boolean.
Short circuiting skips evaluation of the right operand. This is useful for defaults and guarded work, but hiding required side effects inside a logical expression makes behavior fragile. Logical assignment evaluates the left property reference once and assigns only when its condition is met.
JavaScript forbids mixing `??` directly with `&&` or `||` without grouping because the intended precedence is too easy to misread. Optional chaining also short circuits only along a continuous chain; grouping can end the protection. Keep access and fallback expressions small.
Number uses binary floating-point and cannot represent every decimal exactly. Check finiteness and domain range, compare measured decimals with suitable tolerances, and use an integer minor unit or decimal library when exact financial arithmetic is required. Remainder `%` is not a mathematical modulo for negative operands.
BigInt represents arbitrary-size integers but cannot be mixed directly with Number arithmetic. Division truncates toward zero, unary plus is unavailable, and JSON needs an explicit string or tagged encoding. Choose one numeric domain at a boundary and convert with range and precision checks.
Number bitwise operators convert operands to 32-bit integers, which can truncate larger values. Use them for defined masks and low-level representations, not as a shortcut to coerce arbitrary numbers to integers. BigInt has its own supported bitwise operations without unsigned right shift.
`in` checks a property across the prototype chain, while `Object.hasOwn` checks an own property. `instanceof` follows constructor and prototype behavior and can be affected by realms or customization. Validate external records by schema rather than treating any one operator as proof of trusted type.
`typeof` reports broad runtime categories and famously reports null as object; use a null check and Array.isArray where those distinctions matter. `void` evaluates an expression and returns undefined, while unary plus requests Number conversion and rejects BigInt. Prefer named conversion functions when input validation matters.
`delete` removes a configurable object property; it does not delete lexical variables and it leaves a hole when used on an array index. Use array removal methods for sequence semantics and Reflect.deleteProperty when code needs an explicit boolean result from a dynamic property operation.
Operators are symbols or keywords that perform operations on values, such as arithmetic, comparison, assignment, logical checks, and type checks.
<code>==</code> compares values after type conversion, while <code>===</code> compares both value and type. In most code, prefer <code>===</code>.
<code>||</code> falls back for any falsy value, including <code>0</code> and empty strings. <code>??</code> falls back only for <code>null</code> or <code>undefined</code>.
Explore 500+ free tutorials across 20+ languages and frameworks.