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
letandconst. - 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
- Create a counter that starts at 0, add 3 using
+=, then increment. Expected counter: 4. - Write a function
sum(a = 0, b = 0)that returns the sum. Test with no args → expected 0. - Given
const limit = 0, setconst display = limit ?? 10. What isdisplay? Expected: 0. - Evaluate
2 + 3 * 4vs(2 + 3) * 4. Expected: 14 and 20. - Demonstrate a case where
++iandi++behave differently in an expression; explain why.
Common mistakes
- Mutating a
constbinding confusion: you cannot reassign aconstvariable, 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 like0to be replaced unexpectedly.