Classes and objects
A class is a blueprint, and a blueprint is not something you can interact with. A house plan has no rooms to walk through until someone builds the house. In the same way, the Dog class describes dogs without being one. To get an actual dog you create an instance of the class. An instance is also called an object, and the two words mean the same thing here.
The new keyword
You create an object by writing new, then the class name, then parentheses:
let rex = new Dog();
The line does three things:
new Dog()builds a freshDogobject. If the class has a constructor,newruns it, and the expression evaluates to the finished object.let rexdeclares a variable namedrex.- The
=stores the new object in that variable, sorexnow refers to it.
The parentheses are required in practice, because they are where the constructor's arguments go. Later lessons pass values there, as in new Dog("Rex", 4).
Many objects from one class
You can call new Dog() as often as you like. Every call returns a brand-new object that is independent of all the others:
let rex = new Dog();
let buddy = new Dog();
let luna = new Dog();
All three are Dog objects, and rex instanceof Dog is true, yet they are three different objects. They share the blueprint but have separate lives, so changing one does not change the others:
class Dog {
}
let rex = new Dog();
let buddy = new Dog();
rex.name = "Rex";
console.log(rex.name); // Rex
console.log(buddy.name); // undefined
console.log(rex === buddy); // false
The === comparison on objects asks whether both sides are the very same object, not whether they look alike. Two dogs made by two separate new calls are never ===, even when both are empty.
Variables hold references
A variable that holds an object really holds a reference to it. Copying the variable copies the reference, not the object:
let rex = new Dog();
let alias = rex;
alias.name = "Rex";
console.log(rex.name); // Rex
console.log(rex === alias); // true
Here there is still one dog with two names for it. Only new makes another one.
The exercise, step by step
The Dog class is already written. The checks at the bottom of the starter code read the variables rex, buddy and luna, so each must exist:
- Create the first dog. Below the class, write
let rex = new Dog();. Thenewkeyword runs the class constructor and returns the freshly built object. - Create the second dog. On the next line, store another
new Dog()inbuddy. It is a different object fromrex. - Create the third dog and store it in
luna. One class can produce any number of objects.
class Dog {
}
let rex = new Dog();
let buddy = new Dog();
let luna = new Dog();
if (rex != null) console.log("rex exists");
if (buddy != null) console.log("buddy exists");
if (luna != null) console.log("luna exists");
It prints:
rex exists
buddy exists
luna exists
The check rex != null is true for any value that is neither null nor undefined, so it is true for a real object. If a variable was never declared, the check does not print anything: JavaScript stops with a ReferenceError instead.
Common mistakes
- Forgetting
new.let rex = Dog();throwsTypeError: Class constructor Dog cannot be invoked without 'new'. A class must be instantiated withnew. - Reusing a variable name. Declaring
let rextwice in the same scope is aSyntaxError. Give each dog its own name, or use an array when the number of dogs is not fixed. - Expecting one
newto make several objects.let a = new Dog(); let b = a;creates one dog. Every new object needs its ownnew. - Using
constand then reassigning.constis a good choice for a variable that always holds the same object. Properties of that object can still change, butrex = new Dog()on aconstthrowsTypeError: Assignment to constant variable.This lesson usesletto match its exercise.
Key takeaways
- An object is an instance of a class, created with
new ClassName(). - Each
newcall builds a separate, independent object. - A variable holds a reference to its object, and
===on two objects is true only for the same object. - Calling a class without
newis an error.