JavaScript Tutorial

JavaScript Operators and Expressions: Complete Guide

Master JavaScript operators and expressions. Learn about arithmetic, assignment, comparison, logical operators, and how to build expressions. Complete guide for beginners with practical examples.

Welcome back! 👋 In the previous lessons, you learned about variables, data types, and type conversion. Now it's time to learn how to perform operations on those values using operators and how to combine them into expressions.

Operators are the building blocks of any programming logic. They allow you to manipulate data, make comparisons, perform calculations, and control program flow. Let's dive in!


What are Operators?

An operator is a special symbol or keyword that performs an operation on one or more values (called operands) and produces a result.

Simple Analogy

Think of operators like mathematical symbols you learned in school:

  • + means "add these numbers"
  • - means "subtract these numbers"
  • = means "assign this value"

JavaScript operators work the same way but can do much more than just math!

Basic Example

let a = 10;      // = is an assignment operator
let b = 5;
let sum = a + b; // + is an arithmetic operator

console.log(sum); // 15

In this example:

  • = is the assignment operator (assigns values)
  • + is the arithmetic operator (adds values)
  • a, b, 10, 5 are operands (values being operated on)

Types of Operators Based on Operand Count

JavaScript operators can be classified by how many operands they work with:

1. Unary Operators (One Operand)

Work with a single value:

let x = 5;

console.log(-x);     // -5 (unary negation)
console.log(++x);    // 6 (increment)
console.log(typeof x); // "number" (typeof operator)
console.log(!true);  // false (logical NOT)

2. Binary Operators (Two Operands)

Work with two values (most common):

let a = 10;
let b = 5;

console.log(a + b);  // 15 (addition)
console.log(a > b);  // true (comparison)
console.log(a && b); // 5 (logical AND)

3. Ternary Operator (Three Operands)

JavaScript has only one ternary operator:

let age = 18;
let status = age >= 18 ? "adult" : "minor";
console.log(status); // "adult"

// condition ? valueIfTrue : valueIfFalse

Categories of JavaScript Operators

JavaScript provides several categories of operators. Let's explore each one:

1. Arithmetic Operators

Perform mathematical calculations.

let x = 10;
let y = 3;

console.log(x + y);  // 13 - Addition
console.log(x - y);  // 7  - Subtraction
console.log(x * y);  // 30 - Multiplication
console.log(x / y);  // 3.333... - Division
console.log(x % y);  // 1  - Modulus (remainder)
console.log(x ** y); // 1000 - Exponentiation (10³)

Special operators:

let count = 5;
count++;             // 6 - Increment by 1
count--;             // 5 - Decrement by 1

Learn more: Arithmetic Operators →

2. Assignment Operators

Assign values to variables.

let x = 10;          // Simple assignment

x += 5;              // x = x + 5 → 15
x -= 3;              // x = x - 3 → 12
x *= 2;              // x = x * 2 → 24
x /= 4;              // x = x / 4 → 6
x %= 4;              // x = x % 4 → 2
x **= 3;             // x = x ** 3 → 8

Learn more: Assignment Operators →

3. Comparison Operators

Compare two values and return a boolean (true or false).

let a = 10;
let b = 5;

console.log(a > b);   // true  - Greater than
console.log(a < b);   // false - Less than
console.log(a >= 10); // true  - Greater than or equal
console.log(a <= 5);  // false - Less than or equal
console.log(a == 10); // true  - Equal (with type coercion)
console.log(a === 10);// true  - Strict equal (no type coercion)
console.log(a != b);  // true  - Not equal
console.log(a !== b); // true  - Strict not equal

Learn more: Comparison Operators →

4. Logical Operators

Perform logical operations on boolean values.

let isAdult = true;
let hasLicense = false;

console.log(isAdult && hasLicense); // false - AND (both must be true)
console.log(isAdult || hasLicense); // true  - OR (at least one must be true)
console.log(!isAdult);              // false - NOT (inverts boolean)

// With non-boolean values
console.log(5 && 10);               // 10 (returns last truthy value)
console.log(0 || "default");        // "default" (returns first truthy value)
console.log("" ?? "fallback");      // "fallback" - Nullish coalescing

Learn more: Logical Operators →

5. String Operators

Work with strings.

let firstName = "John";
let lastName = "Doe";

// Concatenation with +
let fullName = firstName + " " + lastName;
console.log(fullName); // "John Doe"

// Concatenation with +=
let greeting = "Hello";
greeting += " World";
console.log(greeting); // "Hello World"

// Template literals (recommended)
let message = `${firstName} ${lastName}`;
console.log(message); // "John Doe"

Learn more: String Operators →

6. Type Operators

Check or manipulate types.

// typeof - Returns type as string
console.log(typeof 42);          // "number"
console.log(typeof "hello");     // "string"
console.log(typeof true);        // "boolean"
console.log(typeof undefined);   // "undefined"
console.log(typeof {});          // "object"

// instanceof - Checks if object is instance of class
let arr = [1, 2, 3];
console.log(arr instanceof Array); // true
console.log(arr instanceof Object); // true

7. Conditional (Ternary) Operator

Shorthand for if-else statements.

// Syntax: condition ? valueIfTrue : valueIfFalse

let age = 20;
let canVote = age >= 18 ? "Yes" : "No";
console.log(canVote); // "Yes"

// Equivalent to:
let canVote2;
if (age >= 18) {
  canVote2 = "Yes";
} else {
  canVote2 = "No";
}

8. Other Special Operators

Optional Chaining (?.) - ES2020:

let user = { name: "John", address: { city: "NYC" } };

console.log(user?.name);           // "John"
console.log(user?.address?.city);  // "NYC"
console.log(user?.phone?.number);  // undefined (no error!)

// Without optional chaining (would throw error)
// console.log(user.phone.number);  // ❌ TypeError

Nullish Coalescing (??) - ES2020:

let value1 = null ?? "default";      // "default"
let value2 = undefined ?? "default"; // "default"
let value3 = 0 ?? "default";         // 0 (0 is not null/undefined)
let value4 = "" ?? "default";        // "" (empty string is not null/undefined)

// Compare with OR operator
let value5 = 0 || "default";         // "default" (0 is falsy)
let value6 = "" || "default";        // "default" ("" is falsy)

Spread Operator (...) - ES6:

// Array spreading
let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]

// Object spreading
let person = { name: "John", age: 30 };
let employee = { ...person, job: "Developer" };
console.log(employee); // { name: "John", age: 30, job: "Developer" }

What are Expressions?

An expression is any valid unit of code that resolves to a value. Think of it as a piece of code that produces a result.

Examples of Expressions

// Simple expressions
5                    // → 5
"hello"              // → "hello"
true                 // → true

// Arithmetic expressions
5 + 3                // → 8
10 * 2               // → 20
(4 + 5) * 2          // → 18

// String expressions
"Hello" + " World"   // → "Hello World"

// Logical expressions
5 > 3                // → true
true && false        // → false

// Function call expressions
Math.max(10, 20)     // → 20

// Variable expressions
let x = 5;
x + 10               // → 15

// Complex expressions
(10 + 5) * 2 / (3 - 1)  // → 15

Key Point: Expressions Produce Values

Every expression can be assigned to a variable because it produces a value:

let result = 5 + 3;              // Expression: 5 + 3 → 8
let isValid = age >= 18;         // Expression: age >= 18 → true
let greeting = "Hello " + name;  // Expression: "Hello " + name → "Hello John"

Expressions vs Statements

This is an important distinction in JavaScript!

Expression

Produces a value - can be used anywhere a value is expected.

// These are all expressions (produce values)
5 + 3
"hello".toUpperCase()
true && false
x > 10
Math.random()
age >= 18 ? "adult" : "minor"

Statement

Performs an action - doesn't necessarily produce a value.

// These are statements (perform actions)
let x = 5;                    // Variable declaration statement
if (x > 10) { }               // If statement
for (let i = 0; i < 10; i++) // For loop statement
function greet() { }          // Function declaration statement

Key Differences

// ✅ Expression can be used in assignments
let result = 5 + 3;           // 5 + 3 is an expression

// ❌ Statement cannot be used in assignments
let result = if (true) { 5 }; // ❌ Syntax Error - if is a statement

// ✅ Expression can be used as function argument
console.log(5 + 3);           // 5 + 3 is an expression

// ❌ Statement cannot be used as function argument
console.log(let x = 5);       // ❌ Syntax Error - let is a statement

Visual Summary

EXPRESSION                    STATEMENT
──────────                    ─────────
Produces a value              Performs an action
Can be assigned              Cannot be assigned
5 + 3                        let x = 5;
"hello"                      if (condition) { }
true && false                for (;;) { }
x > 10                       function name() { }
Math.random()                return value;

Expression Statements

Some expressions can also be statements when used alone:

// Expression used as a statement
5 + 3;                // Valid but useless (value not used)
console.log("Hi");    // Function call expression used as statement
x = 10;               // Assignment expression used as statement
counter++;            // Increment expression used as statement

Types of Expressions

Let's explore different types of expressions in JavaScript:

1. Primary Expressions

The simplest expressions - basic values:

// Literal values
42
"hello"
true
null
undefined

// Variable references
let x = 10;
x              // Expression that evaluates to 10

// this keyword
this

2. Arithmetic Expressions

Use arithmetic operators to produce numeric values:

5 + 3          // 8
10 - 4         // 6
6 * 7          // 42
20 / 4         // 5
15 % 4         // 3
2 ** 8         // 256

// Complex arithmetic
(10 + 5) * 2   // 30
100 / (5 + 5)  // 10

3. String Expressions

Produce string values:

"Hello" + " World"              // "Hello World"
"JavaScript".toUpperCase()      // "JAVASCRIPT"
`Total: ${price * quantity}`    // Template literal expression

4. Logical Expressions

Produce boolean values:

5 > 3                // true
x === 10             // true or false
isLoggedIn && isAdmin // Boolean result
age >= 18 || hasPermission // Boolean result

5. Assignment Expressions

Assign values and return the assigned value:

let x = 10;          // Assignment expression (returns 10)
let y = x = 5;       // x = 5, then y = 5 (chained assignment)

// Assignment expressions return values
console.log(x = 20); // Logs 20 (x is also set to 20)

6. Object and Array Expressions

Create objects and arrays:

// Object literal expression
let person = {
  name: "John",
  age: 30
};

// Array literal expression
let numbers = [1, 2, 3, 4, 5];

// Property access expression
person.name        // "John"
numbers[0]         // 1

7. Function Expressions

Create functions as values:

// Function expression
let greet = function(name) {
  return `Hello, ${name}!`;
};

// Arrow function expression
let add = (a, b) => a + b;

// Immediately Invoked Function Expression (IIFE)
(function() {
  console.log("I run immediately!");
})();

8. Call Expressions

Call functions:

Math.max(10, 20)         // 20
console.log("Hello")     // undefined (but has side effect)
[1, 2, 3].map(x => x * 2) // [2, 4, 6]

9. Conditional Expressions

Use ternary operator:

age >= 18 ? "adult" : "minor"
score > 50 ? "Pass" : "Fail"
isLoggedIn ? dashboard() : login()

Combining Expressions

You can combine multiple expressions to create complex expressions:

Simple Combination

let x = 5;
let y = 10;

// Combining arithmetic expressions
let result = (x + y) * 2;         // (5 + 10) * 2 = 30

// Combining comparison expressions
let isValid = x > 0 && y < 20;    // true && true = true

Complex Combination

let price = 100;
let quantity = 3;
let discount = 0.1;

// Complex expression combining multiple operations
let total = (price * quantity) * (1 - discount);
console.log(total); // 270

// Expression with conditional logic
let finalPrice = quantity > 5 
  ? price * quantity * 0.8  // 20% discount
  : price * quantity;

Nested Expressions

// Expressions within expressions
let result = Math.max(
  (10 + 5) * 2,              // Inner expression
  (20 - 5) + 10              // Inner expression
);
console.log(result);         // 30

// Function calls with expression arguments
console.log(
  `Total: ${(price * quantity).toFixed(2)}`
);

Operator Precedence (Order of Operations)

Just like in math, JavaScript follows specific rules about which operations happen first.

Basic Precedence Rules

// Multiplication before addition (like PEMDAS/BODMAS)
let result = 5 + 3 * 2;
console.log(result);  // 11 (not 16!)
// Evaluated as: 5 + (3 * 2) = 5 + 6 = 11

// Division before subtraction
let result2 = 10 - 8 / 2;
console.log(result2); // 6 (not 1!)
// Evaluated as: 10 - (8 / 2) = 10 - 4 = 6

Using Parentheses

Always use parentheses to make your intent clear:

// Without parentheses (confusing)
let x = 10 + 5 * 2;          // 20

// With parentheses (clear intent)
let y = (10 + 5) * 2;        // 30
let z = 10 + (5 * 2);        // 20

// Complex expression (use parentheses!)
let price = 100;
let quantity = 3;
let tax = 0.1;

// Bad - hard to read
let total1 = price * quantity + price * quantity * tax;

// Good - clear intent
let total2 = (price * quantity) + (price * quantity * tax);

// Better - even clearer
let subtotal = price * quantity;
let taxAmount = subtotal * tax;
let total3 = subtotal + taxAmount;

Precedence Hierarchy (High to Low)

// 1. Grouping: ()
(2 + 3) * 4                  // 20

// 2. Member access: . []
person.name
array[0]

// 3. Function calls: ()
Math.max(1, 2)

// 4. Postfix increment/decrement: x++ x--
count++

// 5. Prefix increment/decrement: ++x --x
++count

// 6. Logical NOT: ! Unary: + - typeof
!true
-5
typeof x

// 7. Exponentiation: **
2 ** 3                       // 8

// 8. Multiplication, Division, Modulus: * / %
10 * 2
20 / 4
15 % 4

// 9. Addition, Subtraction: + -
5 + 3
10 - 2

// 10. Comparison: < > <= >=
5 > 3

// 11. Equality: == === != !==
5 === 5

// 12. Logical AND: &&
true && false

// 13. Logical OR: ||
true || false

// 14. Nullish coalescing: ??
null ?? "default"

// 15. Conditional (Ternary): ? :
x > 5 ? "yes" : "no"

// 16. Assignment: = += -= *= /= etc.
x = 10
x += 5

Precedence Example

let result = 2 + 3 * 4 ** 2 / 2 - 1;

// Step-by-step evaluation:
// 1. 4 ** 2 = 16              (Exponentiation first)
// 2. 3 * 16 = 48              (Multiplication)
// 3. 48 / 2 = 24              (Division)
// 4. 2 + 24 = 26              (Addition)
// 5. 26 - 1 = 25              (Subtraction)

console.log(result); // 25

// With parentheses to change order:
let result2 = ((2 + 3) * 4) ** 2 / (2 - 1);
// (5 * 4) ** 2 / 1 = 20 ** 2 / 1 = 400
console.log(result2); // 400

Learn more: Operator Precedence →


Left-to-Right vs Right-to-Left Associativity

When operators have the same precedence, associativity determines the order of evaluation.

Left-to-Right (Most Operators)

// Arithmetic operators evaluate left to right
let result = 10 - 5 - 2;
// (10 - 5) - 2 = 5 - 2 = 3
console.log(result); // 3

// Not: 10 - (5 - 2) = 10 - 3 = 7

Right-to-Left (Assignment and Exponentiation)

// Assignment operators evaluate right to left
let a, b, c;
a = b = c = 5;
// c = 5, then b = 5, then a = 5
console.log(a, b, c); // 5 5 5

// Exponentiation evaluates right to left
let result = 2 ** 3 ** 2;
// 2 ** (3 ** 2) = 2 ** 9 = 512
console.log(result); // 512

// Not: (2 ** 3) ** 2 = 8 ** 2 = 64

Practical Examples

Let's see operators and expressions in real-world scenarios:

Example 1: Calculate Total Price

let itemPrice = 29.99;
let quantity = 3;
let taxRate = 0.08;
let discountPercent = 10;

// Calculate subtotal
let subtotal = itemPrice * quantity;

// Calculate discount
let discountAmount = subtotal * (discountPercent / 100);
let afterDiscount = subtotal - discountAmount;

// Calculate tax
let taxAmount = afterDiscount * taxRate;

// Calculate final total
let total = afterDiscount + taxAmount;

console.log(`Subtotal: $${subtotal.toFixed(2)}`);
console.log(`Discount: -$${discountAmount.toFixed(2)}`);
console.log(`After Discount: $${afterDiscount.toFixed(2)}`);
console.log(`Tax: $${taxAmount.toFixed(2)}`);
console.log(`Total: $${total.toFixed(2)}`);

Example 2: Validate User Input

function validateAge(age) {
  // Complex expression combining multiple conditions
  let isValid = 
    age !== null &&                    // Not null
    age !== undefined &&               // Not undefined
    typeof age === "number" &&         // Is a number
    !isNaN(age) &&                     // Not NaN
    age >= 0 &&                        // Non-negative
    age <= 150 &&                      // Reasonable max
    Number.isInteger(age);             // Whole number
  
  return isValid;
}

console.log(validateAge(25));      // true
console.log(validateAge(-5));      // false
console.log(validateAge(25.5));    // false
console.log(validateAge("25"));    // false
console.log(validateAge(null));    // false

Example 3: Conditional Discount

function calculatePrice(quantity, unitPrice) {
  // Ternary operator for tiered pricing
  let discount = 
    quantity >= 100 ? 0.2 :    // 20% off for 100+
    quantity >= 50 ? 0.15 :    // 15% off for 50+
    quantity >= 20 ? 0.1 :     // 10% off for 20+
    quantity >= 10 ? 0.05 :    // 5% off for 10+
    0;                         // No discount
  
  let subtotal = quantity * unitPrice;
  let discountAmount = subtotal * discount;
  let total = subtotal - discountAmount;
  
  return {
    subtotal: subtotal,
    discount: discountAmount,
    total: total,
    discountPercent: discount * 100
  };
}

console.log(calculatePrice(5, 10));    // No discount
console.log(calculatePrice(15, 10));   // 5% discount
console.log(calculatePrice(75, 10));   // 15% discount

Example 4: Short-Circuit Evaluation

// Using && for conditional execution
let user = { name: "John", age: 30 };

// Only log if user exists
user && console.log(user.name); // Logs "John"

// Using || for default values
let username = user.name || "Guest";
console.log(username); // "John"

let emptyName = "";
let displayName = emptyName || "Anonymous";
console.log(displayName); // "Anonymous"

// Using ?? for more precise defaults
let count = 0;
let displayCount1 = count || 10;   // 10 (0 is falsy)
let displayCount2 = count ?? 10;   // 0 (0 is not null/undefined)

console.log(displayCount1); // 10
console.log(displayCount2); // 0

Common Mistakes with Operators

Mistake 1: Confusing = and ==

// ❌ Bad - assignment in condition
let x = 10;
if (x = 5) {  // This assigns 5 to x, doesn't compare!
  console.log("This always runs");
}
console.log(x); // 5 (changed!)

// ✅ Good - comparison
let y = 10;
if (y === 5) {  // This compares
  console.log("This doesn't run");
}
console.log(y); // 10 (unchanged)

Mistake 2: Not Understanding Operator Precedence

// ❌ Bad - unexpected result
let result = 10 + 5 * 2;
console.log(result); // 20 (expected 30?)

// ✅ Good - explicit with parentheses
let result2 = (10 + 5) * 2;
console.log(result2); // 30

Mistake 3: String Concatenation Instead of Addition

// ❌ Problem
let a = "5";
let b = 3;
console.log(a + b); // "53" (concatenation!)

// ✅ Solution - convert to number
console.log(Number(a) + b); // 8
console.log(+a + b);        // 8

Mistake 4: Incorrect Increment Usage

let x = 5;

// Postfix - returns old value, then increments
console.log(x++); // 5 (logs 5, then x becomes 6)
console.log(x);   // 6

let y = 5;

// Prefix - increments first, then returns new value
console.log(++y); // 6 (y becomes 6, then logs 6)
console.log(y);   // 6

Mistake 5: Truthy/Falsy Confusion

// ❌ Bad - 0 is falsy but valid
function processCount(count) {
  if (!count) {
    console.log("No count provided");
    return;
  }
  console.log(`Count: ${count}`);
}

processCount(0); // "No count provided" (but 0 is valid!)

// ✅ Good - explicit check
function processCount(count) {
  if (count === undefined || count === null) {
    console.log("No count provided");
    return;
  }
  console.log(`Count: ${count}`);
}

processCount(0); // "Count: 0" ✅

Best Practices

1. Use Parentheses for Clarity

// ❌ Hard to read
let result = a + b * c / d - e;

// ✅ Clear intent
let result = a + ((b * c) / d) - e;

2. Always Use === Instead of ==

// ❌ Avoid == (type coercion)
if (value == 0) { }

// ✅ Use === (strict equality)
if (value === 0) { }

3. Be Explicit with Type Conversions

// ❌ Relying on coercion
let total = "5" + 3; // "53"

// ✅ Explicit conversion
let total = Number("5") + 3; // 8

4. Use Meaningful Variable Names

// ❌ Bad
let x = p * q * (1 - d);

// ✅ Good
let price = unitPrice * quantity * (1 - discountRate);

5. Break Complex Expressions into Steps

// ❌ Hard to understand
let result = ((a + b) * c - d) / (e + f) ** 2;

// ✅ Easier to understand
let sum = a + b;
let product = sum * c;
let difference = product - d;
let base = e + f;
let exponent = base ** 2;
let result = difference / exponent;

6. Use Template Literals for String Building

// ❌ Hard to read
let message = "Hello " + name + ", you have " + count + " new messages.";

// ✅ Clear and readable
let message = `Hello ${name}, you have ${count} new messages.`;

Summary and Next Steps

Congratulations! 🎉 You now understand the fundamentals of operators and expressions in JavaScript.

What You Learned

What operators are - Special symbols that perform operations

Categories of operators:

  • Arithmetic (+, -, *, /, %, **)
  • Assignment (=, +=, -=, etc.)
  • Comparison (==, ===, <, >, etc.)
  • Logical (&&, ||, !)
  • String (+, +=)
  • Type (typeof, instanceof)
  • Ternary (? :)
  • Special (?., ??, ...)

What expressions are - Code that produces values

Expression vs Statement - Expressions produce values, statements perform actions

Types of expressions - Arithmetic, logical, string, conditional, etc.

Operator precedence - Order in which operations are evaluated

Best practices - Using parentheses, strict equality, explicit conversions


Practice Exercise

Create a file called operators-practice.js:

// Operators and Expressions Practice

// Exercise 1: Temperature Converter
function convertTemp(celsius) {
  // Convert Celsius to Fahrenheit: F = (C × 9/5) + 32
  // TODO: Write the conversion using arithmetic operators
}

console.log(convertTemp(0));    // Should be 32
console.log(convertTemp(100));  // Should be 212
console.log(convertTemp(-40));  // Should be -40

// Exercise 2: Discount Calculator
function calculateDiscount(price, quantity) {
  // Apply discount:
  // 10+ items: 10% off
  // 20+ items: 15% off
  // 50+ items: 20% off
  // TODO: Use ternary operator to calculate discount
}

console.log(calculateDiscount(100, 5));   // Should be 500 (no discount)
console.log(calculateDiscount(100, 15));  // Should be 1350 (10% off)
console.log(calculateDiscount(100, 25));  // Should be 2125 (15% off)

// Exercise 3: Complex Expression
let a = 5;
let b = 10;
let c = 2;

// Without running the code, what is the result of:
let result = a + b * c ** 2 / 4 - 3;

// Then run it and check if you were correct!
console.log(result);

// Exercise 4: Validate Email (simple)
function isValidEmail(email) {
  // Check if email contains @ and .
  // TODO: Use logical operators
}

console.log(isValidEmail("test@example.com"));  // true
console.log(isValidEmail("test@example"));      // false
console.log(isValidEmail("testexample.com"));   // false

What's Next?

In the next lessons, you'll explore each operator category in detail:

After that:

  • Assignment Operators
  • Comparison Operators
  • Logical Operators
  • Operator Precedence

Each lesson will provide comprehensive coverage with practical examples and exercises!