Programming (JavaScript basics) → Lesson 3

Programming Lesson 3: Variables, defaults & operators

Named references, assignment, operator behavior, and how to choose safe defaults.

Learning goals

  • Understand variables as named references to values.
  • Explain differences between let and const.
  • Use assignment and update operators safely.
  • Apply defaults via parameters and fallback patterns (?? vs ||).
  • Be aware of operator precedence and side effects.

Variables

A variable is a named reference that points to a value. You use the name to read or update the stored value.

let vs const

let creates a binding you can reassign (mutable binding). const creates a binding that cannot be reassigned; the value referenced may still be mutable (objects), but the binding stays fixed.

let score = 0;
score = score + 5; // ok

const name = 'Ava';
// name = 'Ben'; // error: cannot reassign a const binding

Assignment and update operators

Basic assignment: =. Update operators are shorthand for common patterns.

let x = 10;
x += 5; // x = x + 5 -> 15
x -= 3; // x = x - 3 -> 12
x *= 2; // x = x * 2 -> 24
x /= 4; // x = x / 4 -> 6

Increment / decrement:

let i = 0;
i++; // i becomes 1 (post-increment returns previous value)
// Prefer explicit updates when clarity matters:
i = i + 1; // clear and unambiguous

Note: ++i (pre-increment) changes the value then returns it; i++ returns the original value then increments. This can be confusing in expressions.

Comparison operators

Comparison operators test the relationship between two values and return a boolean (true or false). They are essential for making decisions in your code.

Operator Name What it does Example Result
== Equal to Checks if two values are equal (uses type coercion) 5 == '5' true
=== Strictly equal to Checks if two values are equal without type coercion (compares type and value) 5 === '5' false
!= Not equal to Checks if two values are not equal (uses type coercion) 5 != '5' false
!== Strictly not equal to Checks if two values are not equal without type coercion 5 !== '5' true
> Greater than Checks if the left value is greater than the right value 10 > 5 true
>= Greater than or equal to Checks if the left value is greater than or equal to the right value 5 >= 5 true
< Less than Checks if the left value is less than the right value 3 < 8 true
<= Less than or equal to Checks if the left value is less than or equal to the right value 8 <= 8 true

Comparison examples

const age = 18;
const score = 72;

if (age >= 18) {
    console.log('You are an adult'); // prints
}

if (score > 100) {
    console.log('Perfect score'); // does not print
}

if (score < 70) {
    console.log('Failed'); // does not print
}

Prefer === over ==

Use === (strict equality) in your code. The difference matters:

0 == false // true (type coercion)
0 === false // false (different types)

'' == false // true (type coercion)
'' === false // false (different types)

Logical operators

Logical operators combine or modify boolean values. They are commonly used in conditions for loops, if statements, and while loops.

Operator Name What it does Example Result
&& AND Returns true only if both sides are true true && false false
|| OR Returns true if at least one side is true true || false true
! NOT Inverts the boolean value (true becomes false, false becomes true) !true false

Truth tables for AND and OR

AND (&&): Both sides must be true

Left Right Result
true true true
true false false
false true false
false false false

OR (||): At least one side must be true

Left Right Result
true true true
true false true
false true true
false false false

Logical operators in conditions

const age = 25;
const hasLicense = true;

// AND: both conditions must be true
if (age >= 18 && hasLicense) {
    console.log('You can drive'); // prints
}

// OR: at least one condition must be true
const isWeekend = true;
const isHoliday = false;
if (isWeekend || isHoliday) {
    console.log('No work today'); // prints
}

// NOT: inverts the condition
if (!hasLicense) {
    console.log('Get a license'); // does not print
}

Combining logical operators

const age = 16;
const parentConsent = true;

// Complex condition: age is 16-18 AND has parent consent
if ((age >= 16 && age < 18) && parentConsent) {
    console.log('Allowed with parental permission');
}

// NOT with AND: neither condition is true
const isBanned = false;
const isBlocked = false;
if (!isBanned && !isBlocked) {
    console.log('Access granted'); // prints
}

Short-circuit evaluation

&& stops evaluating as soon as it finds a false value. || stops evaluating as soon as it finds a true value. This can improve performance and prevent errors.

const user = null;

// With AND: if user is null, the second part never runs
if (user && user.age > 18) {
    console.log('Adult user'); // does not print, no error
}

// With OR: if the first value is true, the second is never checked
const isAdmin = true;
if (isAdmin || user.role === 'admin') {
    console.log('Has admin access'); // prints (second part not checked)
}

Operator precedence

Operators have an evaluation order. Use parentheses to make intent explicit.

const result = 2 + 3 * 4; // 14, multiplication before addition
const safe = (2 + 3) * 4; // 20, parentheses change order

Defaults and fallbacks

Function parameter defaults

function greet(name = 'friend') {
    return 'Hello, ' + name;
}

greet(); // 'Hello, friend'
greet('Ava'); // 'Hello, Ava'

Fallback patterns: || vs ??

|| returns the right-hand operand when the left is falsy (includes 0, empty string, null, undefined). ?? (nullish coalescing) only falls back for null or undefined, preserving values like 0 or ''.

const a = 0;
const b = a || 10;   // b = 10 (0 is falsy)
const c = a ?? 10;   // c = 0  (0 is not null/undefined)

const s = '';
const s1 = s || 'default'; // 'default'
const s2 = s ?? 'default'; // ''

Side effects vs pure computation

A pure computation returns a value without changing external state. A side effect modifies state or interacts with the outside world. Prefer pure code for predictability; isolate side effects to the edges of your program.

// pure
function add(a, b) { return a + b; }

// impure (side effect)
let total = 0;
function addToTotal(n) { total += n; }

Examples

Score updates

let score = 0;
score += 10; // score = 10
score++;     // score = 11

Default parameters

function makePoint(x = 0, y = 0) {
    return { x, y };
}

makePoint(); // { x: 0, y: 0 }

?? vs || example

const input = 0;
const value1 = input || 5;  // 5
const value2 = input ?? 5;  // 0

Practice tasks

  1. Create a counter that starts at 0, add 3 using +=, then increment. Expected counter: 4.
  2. Write a function sum(a = 0, b = 0) that returns the sum. Test with no args → expected 0.
  3. Given const limit = 0, set const display = limit ?? 10. What is display? Expected: 0.
  4. Evaluate 2 + 3 * 4 vs (2 + 3) * 4. Expected: 14 and 20.
  5. Demonstrate a case where ++i and i++ behave differently in an expression; explain why.

Common mistakes

  • Mutating a const binding confusion: you cannot reassign a const variable, but you can mutate an object it references. Use clear naming and avoid surprising mutations.
  • Precedence surprises: forgetting parentheses can change results — use parentheses for clarity.
  • Using || when ?? is intended, causing valid values like 0 to be replaced unexpectedly.