Computer Science Fundamentals: How JavaScript Works
Introduction
Icebreaker: What Happens Behind the Scenes?
Have you ever wondered what actually happens when you write const name = "Alex"? Where does that data go? How does JavaScript keep track of it? What's really going on when you reassign a variable?
Today, you'll peek behind the curtain and understand how JavaScript manages data in memory—and why that matters when you write code.
And unlike magic shows or professional wrestling, peeking behind the curtain doesn't spoil the fun. It makes you a better programmer by giving you a deeper understanding of how your code works.
What You Already Know
In Program Structure, you learned:
- ✅ JavaScript's primitive types (strings, numbers, booleans)
- ✅ How to create variables with
constandlet - ✅ Basic operators (arithmetic, comparison, logical)
- ✅ Template literals for combining strings and variables
This lesson builds on that foundation. You know the "what"—now you'll learn the "how" and "why."
What You'll Learn Today
- Memory model: Where data lives and how JavaScript finds it
- References vs. values: What variables actually store
- Immutability: Why primitive values can't be changed (in depth)
- Type system deep-dive: How JavaScript decides what's valid
- Conditional logic: Teaching computers to make decisions (NEW)
Before You Begin
GitHub Classroom Repository: You should have received a link to a GitHub Classroom assignment. Accept the assignment and clone the repository to your local machine. This is where you'll write code exercises and projects for this lesson. See the README.md in your repository for setup instructions. Those instructions are meant to work hand-in-hand with the content of this lesson, so make sure to follow along with both.
Core Concept: The Memory Model
Data and The Heap
Every value you create in JavaScript lives somewhere in your computer's memory:
"Hello, World!"; // This string exists in memory
42; // This number exists in memory
true; // This boolean exists in memory
JavaScript uses a region of memory called the heap to store all data. Think of it as a warehouse where every value gets a storage location.
Key insight: When you create a value, JavaScript:
- Allocates space in the heap
- Stores the value there
- Gives you a way to access it (a reference)
References: How We Access Data
A reference is like an address label—it points to where the actual data lives.
const name = "Alex"; // `name` is a REFERENCE to the string "Alex"
What's happening:
- JavaScript stores
"Alex"somewhere in the heap nameholds a reference (pointer) to that location- When you use
name, JavaScript follows the reference to retrieve"Alex"
Analogy: Think of variables as mailbox labels. The label (name) isn't the mail—it just tells you where to find it.
Garbage Collection: Automatic Cleanup
When a value has no references pointing to it, JavaScript automatically removes it from memory (garbage collection):
let x = "temporary"; // Create value, `x` references it
x = "new value"; // `x` now references something else
// "temporary" has no references → GARBAGE COLLECTED
Why this matters: You don't manually manage memory in JavaScript. Understand references, and memory takes care of itself.
Checkpoint 1: Memory Model
Before moving on, write answers to these in your handwritten notes ✍️. Handwriting slows you down just enough to actually process what you're reading instead of skimming past it.
- When you create a value like
42, where does it get stored? - What is a variable actually storing—the value itself, or something else?
- What happens to a value when nothing references it anymore?
- Draw a simple diagram: show a variable
agethat references the number25in the heap.
Binding Data to References
You've used const and let before. Now let's understand what they're really doing.
Creating References
/**
* `=` is an ASSIGNMENT OPERATOR. It takes whatever is on the right side
* and assigns it to the left.
*
* Right side: A STRING (we know because it's wrapped in quotes)
* Left side:
* 1. `const` reserves space in memory
* 2. `js` is the name for that memory location
* 3. `=` binds the string value to this reference
*/
const js = "JavaScript"; // Semicolons are optional but recommended
const java = "Java"; // Each creates a separate reference
// If we intend to RE-ASSIGN, use `let`
let x = 3;
/**
* RE-ASSIGN the reference `x` to a NEW value.
*
* What happens to `3`?
* - If nothing else references it, garbage collector removes it
* - A NEW value `4` is created in the heap
* - `x` now points to this new location
*/
x = 4;
Key distinction:
const: Reference is permanent (can't rebind)let: Reference can be updated (rebind to a new value)
Quick Review: Primitives You Know
From Program Structure, recall the primitive types. Here's a brief refresher with memory context:
Numbers
Any numeric value without quotes: 42, 3.14, -7, 0, 2.998e8 (scientific notation)
JavaScript doesn't distinguish between integers and decimals—they're all type number.
Edge cases:
Infinityand-Infinity(result of division by zero)NaN("Not a Number"—ironically, it IS typenumber)
If you see NaN, something went wrong with a calculation (e.g., 0/0 or "hello" * 2).
Memory note: Each number is a separate value in the heap.
Strings
Text wrapped in quotes: "Hello, World!", 'JavaScript', `template literal`
Key point: If it's in quotes, it's a string. Even "25" is a string, not a number.
For simplicity, use double quotes for regular strings like you would in English dialogue.
Memory note: Each string, even identical ones created separately, occupies space in the heap.
Booleans
Logical values: true or false (no quotes!)
Used for decision-making: "Is this condition true? Then do this."
Not booleans:
"true"and"false"are strings1and0are numbers (though they coerce to boolean in some contexts)
Memory note: Just two possible values, but still stored in the heap when referenced.
Empty Values
JavaScript has two special values that represent the absence of a meaningful value: null and undefined.
The difference in meaning between undefined and null is an accident of JavaScript's design, and it doesn't matter most of the time. In cases where you actually have to concern yourself with these values, I recommend treating them as mostly interchangeable. Eloquent JavaScript
For now, just know they exist. JavaScript returns them to you; you rarely create them intentionally.
Checkpoint 2: References and Primitives
Answer these before moving on:
- What's the difference between
constandletin terms of references? - True or false: When you reassign a
letvariable, you're changing the original value in memory. - What happens to the old value when you reassign a variable?
- Is
"42"a number or a string? How can you tell? - Write code that creates a reference to the string
"JavaScript", then reassigns it to"TypeScript". Which keyword should you use?
Types: The Classification System
You know JavaScript has types (string, number, boolean). Now understand why types matter.
What Types Do
Types tell JavaScript:
- What operations are valid: You can multiply numbers but not strings (usually)
- How to interpret data:
"5"vs5are fundamentally different - What to return: Operators behave differently based on types
Primitive Data Types
The types you just reviewed (numbers, strings, booleans, null, undefined) are all primitives.
What makes them primitive?
- Single, indivisible values: A number is just a number. A string (even the entire text of Moby Dick in quotes) is one value.
- Immutable: They cannot be changed or broken apart. You can only create new values.
Type Checking with typeof
typeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof null; // "object" (⚠️ JS quirk—this is a bug, ignore it)
Note: typeof always returns a string.
Immutability: Deep Dive
Primitives cannot be modified. This is crucial to understand:
// We use `let` (not `const`) because we intend to reassign
let name = "Mark";
/**
* Where's "Mark"?
* - His memory reference to `name` was destroyed
* - He was garbage collected to clear up memory
* - "Mark" didn't 'change into' "John". He was REPLACED!
*/
name = "John";
Another example:
let count = 5;
count = count + 1; // Creates NEW number (6), rebinds `count`
// Doesn't modify the original 5
One more example — two references, one value:
let greeting = "Hello";
const snapshot = greeting; // snapshot holds a reference to "Hello"
greeting = "Goodbye"; // greeting now points to a NEW string in the heap
// Reassigning `greeting` does NOT affect `snapshot`
// Each variable holds its own independent reference
console.log(greeting); // "Goodbye"
console.log(snapshot); // "Hello"
When you assign one variable to another, you copy the reference — you don't link the variables together. After that, they're independent. Whatever happens to greeting later has no effect on snapshot.
Why this matters: Later, you'll work with objects and arrays (mutable types). Understanding primitive immutability now prepares you for that contrast.
Checkpoint 3: Types and Immutability
Write answers to these in your handwritten notes ✍️. This is the concept students most often get wrong — slowing down here pays off.
- Why does JavaScript have types? What problem do they solve?
- What does
typeof "123"return? - Explain immutability in your own words. Give an example.
- When you write
let x = 5; x = x + 1;, does the original5change in memory? Why or why not? - Name the five primitive types covered so far.
Operators: Quick Review in Context
You learned operators in Program Structure. Let's reinforce them with the memory model in mind.
Key insight: All operations create new values. Nothing mutates primitives.
Arithmetic
5 + 3; // Creates NEW number (8) in memory
5 * 2; // Creates NEW number (10)
5 % 2; // Creates NEW number (1)—remainder
Comparison
These return true or false:
5 === 5; // Compares VALUES in memory → true
5 === "5"; // Different TYPES → false
5 > 3; // true
5 <= 3; // false
Remember: Always use === and !== (strict equality checks type AND value). Never use == or !=.
Logical
These combine boolean values:
true && false; // AND: both must be true → false
true || false; // OR: at least one must be true → true
!true; // NOT: reverses the value → false
String Operations
Concatenation (old way):
"Hello " + "World"; // Creates NEW string → "Hello World"
Template literals (modern way):
const name = "Alex";
`Hello ${name}`; // Creates NEW string → "Hello Alex"
Inside ${}, you can use expressions:
const x = 5;
const y = 3;
`${x} + ${y} = ${x + y}`; // "5 + 3 = 8"
Unary Operators
typeof returns the type as a string:
typeof 42; // "number"
typeof "hello"; // "string"
Increment/Decrement create new values:
let x = 5;
x++; // Creates 6, rebinds x (doesn't modify the original 5)
Checkpoint 4: Operators
Answer these before moving on:
- What's the difference between
===and==? Which should you use? - What does
5 + 3return? What type is the result? - What does
"5" + 3return? Why? - Write a template literal that displays "The sum of 10 and 5 is 15".
- What does
!trueevaluate to?
Dynamic Typing: JavaScript's Flexibility
JavaScript is dynamically typed, which means three things:
- No explicit type declarations: You don't write
const name: string = "Alex"—JavaScript figures it out - Types determined at runtime: JavaScript decides types as code runs
- Type coercion: JavaScript converts types automatically when needed
Type Coercion Examples
"5" + 5; // "55" (string concatenation—`+` with string converts number)
"5" * 2; // 10 (multiplication forces string → number)
"5" - 2; // 3 (subtraction requires numbers)
true + 1; // 2 (boolean → number: true = 1, false = 0)
Pattern: + with strings = concatenation. Other operators = numeric coercion.
When it goes wrong:
"hello" * 2; // NaN (can't convert "hello" to number)
Why This Matters
Dynamic typing makes JavaScript flexible but can lead to unexpected behavior. Understanding type coercion helps you:
- Predict results of mixed-type operations
- Debug
NaNerrors - Write safer code by avoiding implicit conversions
Best practice: Be explicit about types when combining operations.
Checkpoint 5: Dynamic Typing
Answer these before moving on:
- What does "dynamically typed" mean?
- Why does
"5" + 5give"55"but"5" * 2gives10? - When you see
NaN, what does it tell you? - Is
true + truevalid JavaScript? If so, what does it return? - How can you convert the string
"42"to the number42?
Conditional Logic: Teaching Computers to Decide
So far, your programs run the same way every time. But real programs need to adapt based on different situations:
- "If it's raining, suggest an umbrella"
- "If the user is logged in, show the dashboard"
- "If the temperature is above 80, display a warning"
Conditionals let you write code that branches based on whether something is true or false.
The Problem and Solution
Problem: How do you make a program respond differently to different inputs?
Solution: Use if statements to evaluate conditions and execute different code paths.


- The most basic conditional statement is the If Statement
- If something is True do this, otherwise do something else
const isRaining = true;
if (isRaining) {
console.log("Don't forget your umbrella!");
} else {
console.log("Enjoy the sunshine!");
}
Oft times, we have more than two conditions to check. In that case, we can use else if statements to check for additional conditions:
const weather = "cloudy";
/**
* COMPARISON OPERATOR: `===` checks for strict equality (value and type).
*
* 1. Go into memory and find the value associated with the `weather` reference.
* 2. Compare that value to the string "sunny".
* 3. If they are strictly equal, run the code block in the curly braces.
* 4. If not, move on to the next condition and repeat the process.
*/
if (weather === "sunny") {
console.log("It's a bright day!");
} else if (weather === "cloudy") {
console.log("It might rain later.");
} else if (weather === "rainy") {
console.log("Don't forget your umbrella!");
} else {
console.log("Weather condition unknown.");
}
We can also apply some of the logical operators we learned about earlier to create more complex conditions:
const temperature = 75;
if (temperature > 80) {
console.log("It's a hot day!");
} else if (temperature > 60) {
console.log("The weather is pleasant.");
} else {
console.log("It's a bit chilly.");
}
Combining Conditions
Use logical operators (&&, ||, !) to create more sophisticated decisions:
const temperature = 75;
const isRaining = false;
// Using && (AND) - both must be true
if (temperature > 70 && !isRaining) {
console.log("Perfect day for a picnic!");
}
// Using || (OR) - at least one must be true
if (temperature < 32 || isRaining) {
console.log("Better stay inside.");
}
// Complex condition
if (temperature > 80 && temperature < 100 && !isRaining) {
console.log("Great day for the pool!");
}
Key insight: Conditionals make your programs dynamic—they respond differently based on data.
Checkpoint 6: Conditional Logic
Write answers to these in your handwritten notes ✍️. Writing out conditionals by hand helps lock in the syntax before you start typing it.
- What does an
ifstatement do? - What's the difference between
if...else ifand two separateifstatements? - Write a conditional: If
ageis 18 or older, log "Adult". Otherwise, log "Minor". - What does this evaluate to:
5 > 3 && 10 < 5? Why? - How would you check if a variable
scoreis between 80 and 90 (inclusive)?
Wrap-Up
Key Takeaways
Memory Model:
- All data lives in the heap
- Variables are references (addresses) to data
- Garbage collection removes unreferenced values
Types & Immutability:
- Primitives (string, number, boolean, null, undefined) can't be modified
- Operations create new values, never change originals
- JavaScript is dynamically typed (types determined at runtime)
Conditional Logic:
ifstatements make programs respond to conditions- Use
===for comparisons (checks type AND value) - Chain conditions with
else if, combine with&&/||
You're Building a Mental Model
This lesson wasn't about memorizing syntax—you already know the basics from Program Structure. It's about understanding how JavaScript thinks:
- Where data lives (heap)
- How references work (variables point to values)
- Why types matter (operations depend on them)
- How to make decisions (conditionals)
This foundation supports everything you'll build next.
Self-Check: Do You Understand?
Before moving on, test your understanding:
- Draw a diagram: Variable
xreferences the number10in the heap. Thenxis reassigned to20. What happens to10? - Why can't you modify a primitive value?
- What's the difference between
"5"and5in memory? - Write a conditional: If
scoreis 90 or above, log "A". If 80-89, log "B". Otherwise, log "C". - Why does
"hello" - 5giveNaN? - Explain the difference between
constandletin terms of what they allow you to do with references.
Next Steps
With the fundamentals in place, you're ready to:
- Write functions that encapsulate logic
- Work with loops to repeat operations
- Build interactive programs that respond to user input
Keep your notes handy—you'll reference these concepts throughout your programming journey.
Key Terms
- Heap: Region of memory where all JavaScript values are stored
- Reference: A pointer to a location in memory (what variables actually store)
- Garbage Collection: Automatic removal of unreferenced values from memory
- Primitive Data Types: Basic, immutable types (number, string, boolean, null, undefined)
- Immutable: Cannot be changed—new values must be created instead
- Type Coercion: Automatic conversion of values between types
- Dynamically Typed: Types determined at runtime, not declared explicitly
- Conditional Statement: Code that executes different paths based on conditions
- Comparison Operators: Operators that compare values and return booleans (
===,>,<, etc.) - Logical Operators: Operators that combine boolean values (
&&,||,!)