Tutorials Logic, IN info@tutorialslogic.com

JavaScript Operators Arithmetic, Logical, Comparison

JavaScript Expression Semantics

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.

JavaScript 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

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

Arithmetic Operators - JavaScript Example

Arithmetic Operators - JavaScript Example
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

Prefix and Postfix Increment

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.

Prefix vs Postfix

Prefix vs Postfix
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

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

Assignment Operators - JavaScript Example

Assignment Operators - JavaScript Example
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

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

Strict vs Loose Equality

Strict vs Loose Equality
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

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

Logical Operators and Short-Circuiting

Logical Operators and Short-Circuiting
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

Truthy and Falsy Values

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

String Operators

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.

String Concatenation

String Concatenation
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

Ternary Operator

The ternary operator is a short form of an if...else expression. It is useful when choosing between two values.

Ternary Operator - JavaScript Example

Ternary Operator - JavaScript Example
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

Nullish Coalescing Operator

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.

Nullish Coalescing

Nullish Coalescing
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

Optional Chaining Operator

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.

Optional Chaining

Optional Chaining
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

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

Logical Assignment

Logical Assignment
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

Spread and Rest Operators

The ... syntax can be used as spread or rest depending on where it appears. Spread expands values. Rest collects values.

Spread and Rest

Spread and Rest
// 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 Assignment

Destructuring is a special assignment syntax that extracts values from arrays or objects into variables.

Destructuring Assignment - JavaScript Example

Destructuring Assignment - JavaScript Example
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

Type Operators

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

Type and Object Operators

Type and Object Operators
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

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

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.

Precedence Examples

Precedence Examples
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

Complete Practice Example

This example combines arithmetic, comparison, logical, ternary, nullish coalescing, optional chaining, and assignment operators in a simple shopping cart calculation.

Shopping Cart Operators Example

Shopping Cart Operators Example
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 Failure Cases

  • Using = instead of === inside a condition.
  • Using == when strict equality === is safer and clearer.
  • Using || for defaults when 0, false, or "" should be preserved.
  • Forgetting that + concatenates strings when one operand is a string.
  • Writing complex expressions without parentheses, making the code hard to read.
  • Confusing prefix increment ++x with postfix increment x++.

Coercion and Comparison

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.

  • Convert external values before arithmetic and comparison.
  • Choose strict equality, Object.is, or collection sameness deliberately.
  • Use domain-aware text and numeric comparison.
  • Do not collapse every falsy value into absence.

Precedence and Short Circuiting

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.

  • Use parentheses to communicate grouping, not merely satisfy syntax.
  • Remember logical operators return operand values.
  • Keep essential side effects out of short-circuit expressions.
  • Keep optional access and fallback chains continuous and clear.

Numeric and Property Operators

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.

  • Choose numeric representation from precision requirements.
  • Do not mix Number and BigInt arithmetic implicitly.
  • Reserve bitwise coercion for deliberate 32-bit operations.
  • Distinguish inherited properties, own properties, and schema validity.

Unary Operators and Deletion

`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.

  • Combine typeof with checks for null, arrays, and domain shape.
  • Use explicit numeric conversion at validation boundaries.
  • Delete properties only when object ownership permits it.
  • Use sequence methods instead of delete for array elements.
Before you move on

JavaScript Operators Arithmetic, Logical, Comparison Mastery Check

5 checks
  • Convert external operands before calculation.
  • Use strict equality and domain-aware comparison.
  • Parenthesize mixed expressions for intended grouping.
  • Keep required side effects out of short-circuit expressions.
  • Choose Number, BigInt, and bitwise operations deliberately.

JavaScript Questions Learners Ask

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>.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.