Assignment 2: JavaScript Fundamentals

Mastering Prototypes, Closures & Core Concepts πŸš€

⚠️ IMPORTANT: Implementation Guidelines

Complete all TODOs in assignment.js. Each question is INDEPENDENT. You must:

πŸ“Ή Assignment Demonstration

Watch this video to see how the assignment works:

Question 1: Closures - Bank Account System (20 points)

Task: Create a bank account system using closures to maintain private balance and transaction history.

πŸ“– Background:

In real banking software, account balances must be protected from direct manipulation. Closures provide a way to create truly private variables that can only be modified through controlled methods, ensuring data integrity and security.

What is a closure? A closure is created when an inner function "remembers" variables from its outer function's scope, even after the outer function has finished executing. This creates a persistent, private environment.

Real-world use: E-commerce shopping carts, user session management, game player stats, and any system requiring protected state.

Requirements:

  • Implement createBankAccount(initialBalance, accountHolder) that returns an account object
  • Use closures to keep balance and transaction history private (cannot be accessed directly)
  • Return an object with five methods:
    • deposit(amount) - adds to balance (throw error if amount ≀ 0)
    • withdraw(amount) - removes from balance (throw error if insufficient funds or amount ≀ 0)
    • getBalance() - returns current balance
    • getAccountHolder() - returns account holder name
    • getTransactionHistory() - returns array of transaction objects: [{type, amount, balance, timestamp}]
  • Each transaction should record: type ("deposit"/"withdraw"), amount, resulting balance, and timestamp
  • Validate: initialBalance must be β‰₯ 0, accountHolder must be non-empty string

πŸ’‘ Implementation Hints:

  • Creating Private Variables: Declare variables inside the function using let or const. These become private!
  • Structure: Your function should create private variables for balance, holder, and transactions array, then return an object literal with methods
  • Return Pattern: return { method1: function() {...}, method2: function() {...} };
  • Accessing Private Variables: Methods can directly use balance, transactions, etc. without this
  • Validation: Always check inputs BEFORE modifying state. Use typeof to check types
  • Number Validation: Check for typeof x === 'number' AND !isNaN(x) AND isFinite(x)
  • String Validation: Check typeof and use .trim() to remove whitespace before checking if empty
  • Recording Transactions: Each transaction is an object with properties: type, amount, balance, timestamp
  • Timestamps: Use new Date().toISOString() to get ISO format timestamp
  • Array Copying: Return a copy of arrays using spread operator: return [...transactions];
  • Deposit Logic: Validate amount > 0, add to balance, record transaction
  • Withdraw Logic: Validate amount > 0, check sufficient funds, subtract from balance, record transaction

πŸ”‘ Key Concepts:

  • Closure Magic: Variables declared in outer function remain accessible to inner functions
  • Privacy: No way to access balance directly from outside - only through methods!
  • Encapsulation: Implementation details are hidden, only the interface is exposed
  • Data Integrity: All changes must go through validated methods
  • Independence: Each call to createBankAccount() creates a NEW separate environment

Demo: Test your bank account system

πŸ“‹ Expected Functionality:

  • Deposit buttons: When clicked, should add the specified amount to the account balance and display the new balance. A success message should appear in the console showing the transaction.
  • Withdraw buttons: When clicked, should subtract the amount from the balance if sufficient funds exist. If insufficient, an error message should appear in red.
  • View History button: Should display all transactions with type (DEPOSIT/WITHDRAW), amount, resulting balance, and timestamp in the console.
  • Account Independence: Alice's account and Bob's account should operate completely independently - changes to one don't affect the other.
  • Balance Display: The cyan-bordered balance display should update in real-time after each successful transaction.

Account: Alice's Savings

Balance: $0.00

Account: Bob's Checking (Independent)

Balance: $0.00

Question 2: Prototypes - Geometric Shape System (25 points)

Task: Create Circle and Rectangle constructors using prototypes to demonstrate efficient object creation and shared methods.

πŸ“– Background:

JavaScript uses prototype-based inheritance, not classical classes. When you add methods to a constructor's prototype, ALL instances share the same function in memory - this is much more efficient than creating new functions for each object.

Why this matters: Imagine creating 10,000 shapes. With prototypes, you create 10,000 objects but only 2 sets of methods. Without prototypes, you'd create 10,000 objects AND 10,000 copies of each method!

Real-world use: Game engines (thousands of entities), data visualization (thousands of data points), UI frameworks (many components).

Requirements:

  • Create Circle(x, y, radius, color) constructor function with:
    • Properties: x, y, radius, color
    • getArea() - returns Ο€ Γ— radiusΒ²
    • getPerimeter() - returns 2 Γ— Ο€ Γ— radius
    • draw(ctx) - draws circle on canvas
    • contains(px, py) - returns true if point (px,py) is inside circle
  • Create Rectangle(x, y, width, height, color) constructor function with:
    • Properties: x, y, width, height, color
    • getArea() - returns width Γ— height
    • getPerimeter() - returns 2 Γ— (width + height)
    • draw(ctx) - draws rectangle on canvas
    • contains(px, py) - returns true if point (px,py) is inside rectangle
  • ALL methods must be on the prototype (NOT inside constructor)
  • Validate all inputs (numbers must be numbers and positive, color must be string)

πŸ’‘ Key Concepts:

  • Constructor Function: Use function Circle() NOT class Circle
  • this Keyword: In methods, this refers to the specific instance
  • Prototype Chain: Circle.prototype.method is shared by ALL Circle instances
  • Memory Efficiency: 1000 circles = 1000 objects but only 1 set of methods
  • Polymorphism: Both Circle and Rectangle have getArea() but different implementations

Demo: Click canvas to create shapes. Click shapes to select them.

πŸ“‹ Expected Functionality:

  • Add Circle button: Should create a new circle at a random position with a random color and radius. The circle should appear on the canvas immediately.
  • Add Rectangle button: Should create a new rectangle at a random position with random dimensions and color. The rectangle should be drawn on the canvas.
  • Add Random Shape button: Should randomly choose between creating a circle or rectangle.
  • Clear All button: Should remove all shapes from the canvas, leaving it blank.
  • Canvas Click: When you click anywhere on the canvas, it should test the contains() method - if you click inside a shape, it should be highlighted (yellow border) and shape info (type, area, perimeter) should display below the buttons.
  • Shape Methods: Each shape should correctly calculate its area and perimeter. Circles use Ο€, rectangles use standard formulas.
  • Console Output: Information about clicked shapes should appear in the console area below.
Click canvas to test contains() method

Question 3: Advanced Closures - Stopwatch Timer (25 points)

Task: Create a stopwatch system using closures to manage timer state and provide lap timing functionality.

πŸ“– Background:

This question combines closures with timer management. Real applications constantly need to manage asynchronous operations (timers, intervals, API calls) while maintaining state. Closures are perfect for this!

Why closures + timers? You need to track timer IDs, running state, elapsed time, and laps - all while ensuring this data stays private and consistent.

Real-world use: Progress trackers, countdown timers, auto-save systems, polling mechanisms, animation loops, session timeout managers.

Requirements:

  • Implement createStopwatch() that returns a stopwatch object
  • Use closures to maintain private state: timer ID, start time, elapsed time, running status, laps array
  • Return an object with six methods:
    • start() - starts the stopwatch (throw error if already running)
    • stop() - pauses the stopwatch and returns elapsed time in milliseconds
    • reset() - resets to 0 (throw error if currently running)
    • lap() - records current time as a lap (throw error if not running)
    • getTime() - returns current elapsed time in milliseconds
    • getLaps() - returns array of lap times
  • Time should continue accumulating even after stop/start (not reset to 0)
  • Use setInterval to update time every 10ms

πŸ’‘ Key Concepts:

  • Closure State: All variables persist between method calls
  • setInterval: Runs code repeatedly at specified interval
  • clearInterval: CRITICAL! Always clean up or you leak memory
  • Date.now(): Returns current timestamp in milliseconds
  • State Machine: Running/stopped states with validation

Demo: Test your stopwatch implementation

πŸ“‹ Expected Functionality:

  • Start button: Should begin the stopwatch timer, counting up from the current elapsed time. The display should update every 10ms showing MM:SS.mmm format (minutes, seconds, milliseconds).
  • Stop button: Should pause the stopwatch. The time should freeze but NOT reset - clicking Start again should continue from where it stopped.
  • Reset button: Should only work when stopped. It resets the elapsed time to 00:00.000 and clears all lap times.
  • Lap button: Should only work while running. Records the current time as a lap time and displays it in the console below without stopping the timer.
  • Independent Stopwatches: The demo shows two stopwatches side by side. Each should operate completely independently - starting/stopping one doesn't affect the other.
  • Error Handling: Should throw errors if you try to start an already-running stopwatch, record a lap while stopped, or reset while running.
  • Console Output: Lap times should appear in the console area, showing the lap number and time in readable format.

Stopwatch 1

00:00.000

Stopwatch 2 (Independent)

00:00.000

Question 4: Comprehensive Physics Simulation (30 points)

Task: Build a complete bouncing ball physics simulation combining prototypes, closures, animation, and collision detection.

πŸ“– Background:

This capstone question integrates all concepts: prototypes for efficient Ball objects, closures for private animation state, timer management with requestAnimationFrame, and event handling for interaction.

Why this matters: Game engines, physics simulations, data visualizations, and interactive animations all use these exact patterns. This is how real applications are built!

Skills demonstrated: Object-oriented programming, animation loops, state management, collision detection, event handling, and canvas rendering.

Requirements:

  • Create Ball(x, y, radius, color, vx, vy) constructor using prototypes with:
    • Properties: x, y, radius, color, vx (velocity x), vy (velocity y)
    • update(canvasWidth, canvasHeight) - moves ball, bounces off walls
    • draw(ctx) - draws ball on canvas
    • collidesWith(otherBall) - returns true if colliding with another ball
  • Create createBallSimulation(canvas) using closures with:
    • Private state: balls array, animation ID, gravity setting
    • addBall(x, y, radius, color) - adds ball with random velocity
    • start() - begins animation loop using requestAnimationFrame
    • stop() - stops animation
    • clear() - removes all balls
    • setGravity(enabled) - toggles gravity on/off
    • handleClick(event) - adds ball at click position
  • Physics: Balls should bounce off walls (reverse velocity) and have optional gravity
  • When balls collide, they should change color to indicate collision
  • Validate all inputs and throw errors for invalid data

πŸ’‘ Key Concepts:

  • Prototypes: Ball methods shared across all instances
  • Closures: Private balls array and animation state
  • requestAnimationFrame: Smooth 60 FPS animation
  • Physics: Velocity, gravity, collision detection, energy loss
  • State Management: Private state with public interface

Demo: Click canvas to add balls! Toggle gravity to see effects! 🎾

πŸ“‹ Expected Functionality:

  • Start Animation button: Should begin the animation loop, making all balls move smoothly at 60 FPS using requestAnimationFrame.
  • Stop Animation button: Should pause all ball movement by canceling the animation frame. Balls should freeze in place.
  • Add Ball button: Should create a new ball at a random position with random velocity, radius, and color. The ball should immediately appear and start moving if animation is running.
  • Add 10 Balls button: Should add 10 random balls at once to create a more chaotic scene.
  • Toggle Gravity button: Should enable/disable gravity. When enabled, balls should accelerate downward (increasing vertical velocity) and bounce more realistically on the bottom.
  • Clear All button: Should remove all balls from the canvas and reset the scene.
  • Canvas Click: When you click on the canvas, a ball should be created at that exact click position with random velocity and color.
  • Ball Physics: Balls should bounce off all four walls. When they collide with each other, both balls should turn red temporarily to indicate the collision.
  • Console Output: The ball count and collision events should be logged to the console area below.
Click canvas to add balls! Red = collision detected

Question 5: Interactive Fireworks Show (30 points) πŸŽ†

Task: Build a complete fireworks animation system with particle explosions, combining prototypes, closures, and canvas animation.

πŸ“– Background:

This capstone question brings together all the concepts you've learned: prototypes for efficient Particle objects, closures for private animation state, timer management with requestAnimationFrame, and event handling for user interaction.

Real-world application: Particle systems power game effects (explosions, fire, smoke), celebration animations, data visualizations, and interactive graphics. This is how professional animations are built!

What makes this special: You'll create TWO constructor functions (Particle and Firework) that work together, plus a closure-based controller that manages the entire show. This demonstrates composition and system design.

Requirements:

Part A: Particle Constructor (similar to Q2, but with physics)

  • Create Particle(x, y, color, size) constructor using prototypes with:
    • Properties: x, y, color, size, vx (random -2 to 2), vy (random -2 to 2), life (1.0)
    • update() - updates position (x += vx, y += vy), applies gravity (vy += 0.1), decreases life by 0.01
    • draw(ctx) - draws particle with transparency based on life (ctx.globalAlpha = life)
    • isDead() - returns true if life <= 0
  • Validate: x, y, size must be numbers; color must be string

Part B: Firework Constructor

  • Create Firework(x, y, targetY, color) constructor using prototypes with:
    • Properties: x, y, targetY, color, exploded (false), particles (empty array)
    • update() - moves upward (y -= 3), explodes at targetY creating 30-50 Particles
    • draw(ctx) - draws rocket (if not exploded) or all particles (if exploded)
    • isFinished() - returns true when exploded and all particles are dead
  • Validate: x, y, targetY must be numbers; color must be string

Part C: Fireworks Show Controller (Closures)

  • Create createFireworksShow(canvas) using closures with:
    • Private state: fireworks array, animationId, ctx
    • addFirework(x, color) - creates firework at bottom, targeting 20-40% up canvas
    • start() - begins animation loop with requestAnimationFrame
    • stop() - stops animation and clears canvas
    • handleClick(event) - creates firework at click position with random color
  • Animation loop: clear canvas, update/draw all fireworks, remove finished ones

πŸ’‘ Key Concepts:

  • Composition: Firework contains Particles - demonstrates object composition
  • Two Prototypes: Both Particle and Firework use prototype methods
  • Lifecycle: Firework: launch β†’ reach target β†’ explode β†’ particles die β†’ cleanup
  • Closures: Private fireworks array and animationId managed through closure
  • Animation Loop: requestAnimationFrame for smooth 60 FPS animation
  • Memory Management: Remove finished fireworks to prevent memory leaks

Demo: Click canvas to launch fireworks! πŸŽ†βœ¨

πŸ“‹ Expected Functionality:

  • Start Animation button: Should begin the animation loop, making fireworks launch, explode, and fade smoothly at 60 FPS using requestAnimationFrame.
  • Stop Animation button: Should pause all animations by canceling the animation frame and clear the canvas completely.
  • Auto Launch button: Should automatically launch a random firework every 500ms at a random horizontal position with a random color from the palette.
  • Canvas Click: When you click anywhere on the canvas, a firework should launch from the bottom at that X position, shoot upward, explode at about 20-40% of canvas height, and create 30-50 colorful particles.
  • Firework Lifecycle: Each firework should: (1) Launch from bottom as a small dot, (2) Move upward rapidly, (3) Explode at target height creating particles, (4) Particles spread in all directions with random velocities, (5) Particles fall with gravity while fading out, (6) Completely disappear when life reaches 0.
  • Visual Effects: Canvas should have a trail/fade effect (not completely cleared each frame) to create beautiful light streaks. Particles should become more transparent as they age.
  • Memory Management: Finished fireworks (exploded with all particles dead) should be automatically removed from the array to prevent memory leaks.
  • Multiple Fireworks: Multiple fireworks can exist simultaneously, each with independent lifecycles and particle systems.
  • Color Palette: Fireworks should use vibrant colors like red, cyan, yellow, lime, magenta, and orange.
Click canvas anywhere to launch a firework!

Grading Criteria

Question Criteria Points
Q1 (20 pts) Closure implementation & private state 10
Method correctness & transaction logging 6
Error handling & validation 4
Q2 (25 pts) Constructor functions & prototype methods 12
Geometry calculations & drawing 8
Input validation & error handling 5
Q3 (25 pts) Closure-based timer with private state 10
Timer management (start/stop/reset/lap) 10
Validation & error handling 5
Q4 (30 pts) Ball constructor with prototypes 10
Simulation with closures & animation 10
Physics & collision detection 6
Code quality & error handling 4
Q5 (30 pts) Particle & Firework constructors with prototypes 12
FireworksShow with closures & animation 10
Particle system & explosion logic 5
Code quality & error handling 3

Submission Instructions

Key Concepts Being Tested