5.3 Classes and Instances
SLO 3
Describe, design, implement, and test structured programs using currently accepted methodology.
Naming what you have been doing since §5.1 — `Sprite` is a class, and every sprite you made is an instance with its own property values — gives you the vocabulary to describe an object-oriented program before §5.4 asks you to design one.
Learning Objectives
By the end of this section, you will be able to:
- Explain what a class is and what an instance (object) is.
- Use the
newkeyword to create instances from a class. - Distinguish between a class (blueprint) and its instances (objects).
- Explain why classes matter once there is more than one similar object to manage.
- Explain what a property is, and distinguish a value you set explicitly from one that falls back to the class's default.
Every chapter so far has typed new Sprite(...) without ever explaining what new does or what Sprite actually is. This section explains it, using the player, ground, and goal you already built in §5.1-5.2. §5.4 then teaches you to write a class of your own.
5.3.1 What is a Class?
Here's the reveal: Sprite is a class, and every sprite you've created — including the player, ground, and goal from §5.1-5.2 — is an instance of it.
A class is a blueprint for objects. It defines what properties (like color, vel, pos) and behaviors (like collision detection) an object will have. The class itself is just the plan — it doesn't do anything until you build something from it.
A blueprint that defines the properties and behaviors that a type of object will have. A class itself is not an object; it is a template for creating objects.
Notice that you built two whole sections of working game before anyone told you what new meant. That order is deliberate — a blueprint is far easier to use than to read, and this vocabulary lands better attached to sprites you have already moved, bounced and deleted than to an abstract example. If §5.1-5.2 seemed to work fine without this section, that is the point: this section is naming what you were already doing.
Think about a cookie cutter and cookies. Which one is the class and which one is the instance? Write your answer and explain why.
Solution
The cookie cutter is the class — it's the blueprint that defines the shape. Each cookie you cut out is an instance (object) of that class. You can make many cookies from one cutter, and each cookie has the same shape but can be decorated differently (different property values).
For each fact about sprites below, decide: is this true of the class (every sprite, no matter what) or true of one instance (this specific sprite — a different sprite could easily disagree)?
- Every sprite has a
.colorproperty. - This sprite's
.coloris'gold'. new Sprite(x, y, w, h)takes four main arguments.- This sprite was created at position
(200, 100). - Every sprite can be checked for collisions with
colliding().
Solution
1, 3, and 5 are true of the class — every Sprite, without exception, has a .color property, is built the same way, and can be checked for collisions. That's the blueprint. 2 and 4 are true of one instance — a different sprite could just as easily be 'tomato' at (50, 50). The class defines what kind of thing a sprite has; each instance decides what value it has.
5.3.2 What is an Instance?
new builds one instance from that blueprint. player, ground, goal, leftWall, rightWall from §5.2 each have their own independent copy of the sprite's properties (color, vel, pos, and so on), even though they all came from the same Sprite blueprint. Change player.color and it has no effect on ground.color.
A concrete object created from a class blueprint. Each instance has its own independent copy of the properties defined by the class.
Here's the scene from §5.2, minus the goal. Before running anything, predict: if you set player.color = 'lime' at the end of setup, what happens to ground.color and leftWall.color? Write your prediction down, then add the line and check it.
▶ Press Run to see the output…
Solution
Adding player.color = 'lime'; at the end of setup changes only the player. ground.color still reads undefined (it was never set, so it draws in the default color), and leftWall.color still reads 'sienna' exactly as it was set — neither is affected by the player's change. That's three separate Sprite instances, not two: the pattern doesn't stop scaling once you go past a pair. §5.4 is about writing a blueprint of your own instead of only using moSHion's.
5.3.3 Why Classes Matter
Everything you've done with .color, .vel, .pos up to this point was property access on an instance. The Sprite class defines that every sprite has a color, a velocity, and a position. But each sprite gets to set its own values for those properties.
A piece of data that belongs to one instance — .color, .vel, .pos, .bounciness, and .friction are all properties of a Sprite. A property does not have to be explicitly set to exist: if you never assign one, it falls back to whatever default the class defines. .bounciness and .friction default to 0 (§5.2.3); .color has no such default, so reading it before setting it gives undefined.
That last distinction matters more than it looks. Two sprites can disagree on a property for two completely different reasons: because you told them to (explicit values), or because only one of them was ever touched and the other is quietly running on the class's own default.
player.bounciness was explicitly set to 0.6 back in §5.2. What would you expect ground.bounciness to be — undefined, like ground.color was in Try It Now 5.3.3, or something else? Write your prediction, then check it using the scene from Try It Now 5.3.3 (add ground.bounciness to a console.log).
Solution
ground.bounciness is 0, not undefined — because .bounciness is a property every Sprite has a real default for (§5.2.3), unlike .color, which has no default at all until something sets it. This is the same class/instance split as the rest of this section, just one layer deeper: ground.bounciness being 0 isn't a missing value or an error, it's the class's own answer, returned because this particular instance never overrode it. A property is always there — the only question is whether the value came from you or from the blueprint.
Classes let you create your own blueprints too. §5.2.5's goal was one gold square with one distance check written by hand. A game with five goals would mean five copy-pasted distance checks — unless the goal itself became a blueprint you could build more than one of.
Every time you type new Sprite(...), JavaScript does three things: (1) it creates a new empty object, (2) it copies all the Sprite blueprint properties into that object, and (3) it runs any setup code the class defines. The result is a brand-new, independent sprite ready to use. Writing your own class means writing steps 2 and 3 yourself — which is exactly what §5.4 does.
Before writing a real class, predict the shape of one. If you were turning §5.2's goal into a blueprint, what pieces of data would each goal need to remember about itself, and what would it need to be able to do? List both.
Solution
Data each goal needs: its position (or a sprite that already tracks position), and probably whether it's already been collected. Behavior each goal needs: a way to check "has the player reached me?" and a way to "collect myself" (delete the sprite, mark as done). That's exactly a constructor (to set up the data) plus two methods (to provide the behavior) — §5.4 builds precisely this.
Sprite is a class moSHion wrote for you. §5.4 teaches you to write your own — starting with the exact win condition you built by hand in §5.2.5.
Problem Set 5.3
Problem 1. What is a class? Write a definition in your own words.
Solution
Step 1 — Say what it is: A class is a blueprint. It names the properties a kind of object will have and the behaviors it will be able to perform.
Step 2 — Say what it is not:
The blueprint is not itself one of the things. Sprite never appears on the canvas; the sprites you build from it do.
Answer: A class is a template describing what every object of that type will have and be able to do. Any wording that keeps the blueprint-versus-thing-built distinction is fine — "a plan for making objects", "a mould", "a form you fill in". What matters is that the class defines the shape and the instances hold the values.
Problem 2. What does the new keyword do in JavaScript?
Solution
Step 1 — The three things it does:
Per §5.3.3's Insight Note, new creates a new empty object, copies the class's blueprint properties onto it, and runs whatever setup code the class defines.
Step 2 — What you get back:
The finished object. player = new Sprite(200, 100, 40, 40) hands you one independent sprite, ready to use.
Answer: new builds one instance from a class: it makes a fresh empty object, gives it the properties the class defines, runs the class's setup code, and returns the result. Every call to new produces a separate object — which is why changing one sprite never touches another.
Problem 3. What is an instance? How is it different from a class?
Solution
Step 1 — What an instance is: A concrete object built from a class, with its own independent copy of the properties that class defines.
Step 2 — How it differs from the class:
The class says what kind of value a thing has; the instance says what value it actually has. "Every sprite has a .color" is the class. "This sprite's .color is 'gold'" is one instance.
Answer: An instance is an actual object made from the blueprint. One class can produce any number of instances, each holding its own values — the class is the plan, the instance is the thing built to that plan.
Problem 4. If you create two sprites with new Sprite(100, 100, 40, 40) and new Sprite(300, 100, 40, 40), and then change the color of the first one, does the second one's color change? Why or why not?
Solution
Step 1 — Count the objects:
Two separate new Sprite(...) calls means two separate instances. Each got its own copy of the sprite properties when it was built.
Step 2 — Trace the assignment:
Setting the first sprite's .color writes to that object and nothing else. Nothing links one instance's properties to another's.
Answer: No. The second sprite's color is unchanged. They came from the same class, but each instance owns its property values independently — that independence is the whole point of building objects from a blueprint rather than sharing one.
Problem 5. Give a real-world analogy for classes and instances (other than the cookie cutter example).
Solution
Step 1 — Pick a pairing where one thing defines the shape of many: A blueprint for a house and the houses built from it. A recipe and the loaves baked from it. A car model (the design) and the individual cars off the line. A rubber stamp and the prints it makes.
Step 2 — Check it the way the section does: Ask which facts belong to which. "Every house from this blueprint has three bedrooms" is the class. "This house is painted blue" is one instance.
Answer: Any analogy where a single design produces many separate things that share a structure but hold their own values. A blueprint and its houses is the closest fit: one plan, many houses, and repainting one house does not repaint the others.
Problem 6. In the code player = new Sprite(200, 100, 40, 40), which part is the class and which part is the instance?
Solution
Step 1 — Find the blueprint:
Sprite is the class — the name of the type being built from.
Step 2 — Find the thing built:
new Sprite(200, 100, 40, 40) runs the blueprint and produces one object; player is the variable now holding that object.
Answer: Sprite is the class. The instance is the object new Sprite(200, 100, 40, 40) produces, which player refers to. Note the instance is the object, not the variable name — player is just a label pointing at it, and a second variable set to player would point at the same one sprite.
Problem 7. Sort each fact into "true of the class" or "true of one instance": (a) every sprite can call .colliding(), (b) this sprite's diameter is 20, (c) new Sprite(...) always returns a sprite, (d) this sprite's .vel.x is currently 4.
Solution
Step 1 — Apply the test from Try It Now 5.3.2: Ask of each statement: is this true of every sprite without exception (class), or could a different sprite easily disagree (instance)?
Step 2 — Sort them:
- (a) every sprite can call
.colliding()— class. It says "every sprite", and the ability comes from the blueprint. - (b) this sprite's diameter is 20 — instance. Another sprite could be any size.
- (c)
new Sprite(...)always returns a sprite — class. A fact about how the blueprint is used. - (d) this sprite's
.vel.xis currently 4 — instance. And it changes frame to frame.
Answer: Class: (a) and (c). Instance: (b) and (d). The tell is the wording — "every" and "always" describe the blueprint, "this" and "currently" describe one object.
Problem 8. You have three sprites — player, ground, leftWall — and you set player.bounciness = 0.6. Without running any code, what would you expect ground.bounciness and leftWall.bounciness to be, and why?
Solution
Step 1 — Note what was actually changed:
Only player.bounciness was assigned. ground and leftWall were never touched on that property.
Step 2 — Ask what an untouched property returns:
Not nothing. .bounciness is a property the Sprite class gives a real default of 0 (§5.2.3), so an instance that never overrode it reports the class's answer.
Answer: Both ground.bounciness and leftWall.bounciness are 0 — the class default, not an error and not undefined. Setting player.bounciness = 0.6 overrode the default on that one instance and left the other two running on the blueprint's value.
Problem 9. What is a property? Give one example of a property that has a class default (so an untouched instance still returns a real value) and one that does not (so an untouched instance returns undefined).
Solution
Step 1 — Define it:
A property is a piece of data belonging to one instance — .color, .vel, .pos, .bounciness, .friction are all properties of a Sprite.
Step 2 — With a class default:
.bounciness (or .friction). Never assign it and reading it still gives 0, because the class defines that fallback.
Step 3 — Without one:
.color. The class defines no default, so an untouched sprite reads undefined — as ground.color did in Try It Now 5.3.3.
Answer: A property is data held by an instance. .bounciness has a class default of 0; .color has none and reads undefined until something sets it. Both properties exist on every sprite either way — having a default and existing are different questions.
Problem 10. Two sprites both read 0 for .friction, but for different reasons: one because someone wrote sprite.friction = 0, and one because nobody ever touched .friction at all. Can you tell which is which just by reading sprite.friction? Why or why not?
Solution
Step 1 — Compare what you can actually read:
Both report 0. The value is the same number in both cases.
Step 2 — Ask what the value remembers:
Nothing. A property stores a value, not the history of how it got there. There is no record attached to 0 saying "someone typed this" or "the blueprint supplied this".
Answer: No — reading sprite.friction gives 0 for both and cannot distinguish them, because the property holds a value and not its provenance. To tell them apart you have to look at the code that built each sprite. This is the practical edge of §5.3.3's point: two instances agreeing on a property does not tell you why they agree, and that matters the moment you change the class's default and only one of them moves.
Key Terms
| Term | Definition |
|---|---|
| Class | A blueprint that defines the properties and behaviors a type of object will have |
| Instance | A concrete object created from a class blueprint, with its own independent property values |
| Property | A piece of data belonging to one instance; if never explicitly set, it falls back to the class's default value (if the class defines one) |
| new | The JavaScript keyword that creates a new instance from a class |