Intro to JavaScript Classes
Learning Objectives
Students will be able to:
- Describe the use case for classes
- Describe encapsulation in OOP
- Define a class
- Instantiate a class
- Include and use a constructor method in a class
- Define prototype (instance) methods in a class
- Recognize constructor functions (predecessor to classes)
- Define static (class) methods
- Use extends to create a subclass
- Use super within a subclass
Lesson Setup
For this lesson, we're going to code along using a JavaScript
REPL
from repl.it -- you can name it "JavaScript Classes Practice"
.
What Are Classes?
- In object oriented programming (OOP), we use objects to model our application's purpose.
- Classes (as well as their predecessor, constructor functions) are used to create objects.
- Think of classes as the blueprints used to create objects of a certain "type"...
Why Use Classes?
- We've already been creating JS objects using object ___ notation.
- So why do we need classes and/or constructor functions?
- Because the number of a certain type of object needed by an application often varies at runtime; and...
- Classes/constructors provide a convenient way to dynamically create objects as needed.
Encapsulation in OOP
- Encapsulation is a key principle of Object Oriented Programming.
- Encapsulation is the concept of bundling data (properties/attributes) and related behavior (methods) within an object.
- Here comes a graphic depicting this principle...
- Here's a code example of encapsulating data (attributes/properties) & behavior (methods):
var cohort = {
id: 'SEIR Flex',
students: ['Mary', 'Toni', 'Fred'],
instructors: ['Susan', 'Phil'],
addStudent: function(name) {
name = name[0].toUpperCase() + name.substr(1).toLowerCase();
this.students.push(name);
},
pickRandomStudent: function() {
var rndIdx = Math.floor(Math.random() * this.students.length);
return this.students[rndIdx];
}
};
Review Questions
❓ What does the acronym OOP stand for?
❓ In your own words, describe why Classes exist in OOP.
❓ In your own words, describe the OOP principle known as encapsulation.
Defining Classes in JS
-
Here's a minimal class definition that's good for nothing but creating empty objects:
class Vehicle { // Code to define the class's properties and methods }
- Looks similar to defining a function because classes are in fact, special functions, except...
❓ What's different compared to a function?
❓ What's different about the naming convention?
Instantiating a Class
-
Here's a bit more OOP vocab for you:
- instance: An object created by a class
- instantiate: We instantiate a class to create an object
- instantiation: The process of creating an object
-
In JS, we create objects using the
new
keyword when invoking (instantiating) the class:var v1 = new Vehicle();
The constructor Method
-
When a class is being instantiated, the special
constructor
method in the class will automatically be called:class Vehicle { constructor(vin, make) { this.vin = vin; this.make = make; // return is not needed // because the new object is returned by default } } var plane = new Vehicle('X123Y', 'Boeing');
- The purpose of the
constructor
method is to initialize the data properties of the new object being created (represented bythis
). - If there are no properties to initialize, the
constructor
method is optional (a hidden default constructor is called).
Practice - Add a Property
- Modify the
Vehicle
class by adding an additional property namedmodel
. -
Test it out by instantiating another object like this:
var car = new Vehicle('A1234', 'Toyota', 'Camry');
Object Instantiation
-
When we invoke the class prefaced with the
new
keyword, behind the scenes:- JS creates a shiny new object (empty) and assigns it to the
this
keyword. - The
constructor
method is called with the arguments we provided when invoking the class. Remember, theconstructor
method is where we create/initialize properties on the new object assigned tothis
. - After the
constructor
is finished executing, the class automatically returns the shiny new object.
- JS creates a shiny new object (empty) and assigns it to the
- Although the
constructor
method is special because it's called automatically, there's nothing special about how it's defined, other methods are defined the same way...
Defining Methods in a Class
-
There are two types of methods that can be added to a class:
- Prototype (instance) methods, and
- Static (class) methods
- Prototype methods are the most common and are available to be called by any instance of the class.What's an instance?
- Static methods are methods that are called on the class itself and cannot be called by instances.
-
Let's add a
start
method to ourVehicle
class:class Vehicle { // the constructor will always be called constructor(vin, make, model) { this.vin = vin; this.make = make; this.model = model; this.running = false; // default to false } start() { this.running = true; console.log('running...'); } }
- Note that unlike within object literals, methods are not separated by a comma.
Practice - Defining Methods
- Define a
stop
method that sets therunning
property tofalse
and console.logs the message "stopped..."
Overriding Methods
- Thanks to another OOP principle called inheritance, subclasses inherit methods from their parent classes.
- JS is different from class-based languages like Java or Python in that its inheritance implementation is prototype-based. We won't go into prototypes during this lesson, but if you want to learn more, check out the docs here.
-
In JS, virtually every object inherits from the
Object
class and thus inherits it's methods, such astoString
:car.toString() // outputs something like '[object Object]'
-
If we define a method that already exists in the object hierarchy, we "override" it. For example, we can override the Object's
toString
method by adding it to our class:// existing methods above toString() { return 'Vehicle (' + this.vin + ') is a ' + this.make + ' model ' + this.model; }
Test it out.
Review Questions
You've just learned how to define a class and add prototype methods to it. This represents the majority of what you'll need to know about classes - congrats!
Review Questions:
❓ What is the JS keyword used to define a class?
❓ What is the name of the method in a class that is automatically called when we instantiate a class?
❓ What is the main purpose of this method?
❓ What character(s) separate the methods in a class definition?
Hungry for more (Further Reading):
Here is some bonus content to read through if you're hungry for more.
Constructor Functions - B.C. (before classes 😀)
- Before classes arrived via ES2015, we used constructor functions to do the exact same thing as classes.
- Because of the newness of ES2015, much of the code out there is written using constructor functions, however, most new code today is likely to be written as classes.
- It's important that you be able to recognize constructor functions, so let's look at how the
Vehicle
class can be written as a constructor function...
Constructor Functions
function Vehicle(vin, make, model) {
this.vin = vin;
this.make = make;
this.model = model;
this.running = false; // default to false
}
Vehicle.prototype.start = function() {
this.running = true;
console.log('running...');
};
// other 'prototype' (instance) methods defined like above
var car = new Vehicle('A1234', 'Toyota', 'Camry');
- Note that constructor functions are similar to the constructor methods in a class. Also note how instance methods are defined on the function's prototype object.
- Invoking a class and a constructor function works identically.
Static Methods
- Again, static methods are methods that are callable on the class itself - not on its instances.
- Static methods are used typically to implement behavior that does not pertain to a particular instance. For example, we could design the
Vehicle
class so that it tracks every vehicle it creates. We could then write static methods that return how many vehicles have been created, search for vehicles by their make, etc. -
Here's how to define a basic static method:
static about() { console.log("I'm the Vehicle class!"); }
Yup, the only difference is the
static
keyword -
As discussed, you invoke static methods on the class:
// invoke static methods on the class Vehicle.about(); // this will not work car.about();
Inheritance
- Earlier we spoke briefly about inheritance.
- In OOP, inheritance is when a "specialized" subclass is derived from a parent superclass, and thus inherits it's properties and methods.
- For example, a
Payment
class could haveCreditCard
&Cash
subclasses derived from it.
-
We use the
extends
keyword to define a subclass:class Plane extends Vehicle { constructor(vin, make, model, airline) { super(vin, make, model); this.airline = airline; } engageAutoPilot() { console.log('Look Mom, no hands!'); } }
- In a derived class, the
super
keyword represents the parent superclass and must be called before thethis
keyword can be used in the constructor.
Inheritance
-
Now we can create instances of
Plane
like this:var spyPlane = new Plane('secret', 'Lockheed', 'SR-71', 'USA');
- Note how the additional arguments used to initialize subclasses are always provided after those intended for the superclass(es).
- In complex systems, it's not uncommon to have several layers of inheritance - often referred to as an object hierarchy.
Practice - Inheritance
- Define another subclass of the
Vehicle
class namedAutomobile
with an additional property ofnumDoors
and ahonk
method. -
Test it out by instantiating it like this:
var fastCar = new Automobile('TS123Z', 'Tesla', 'P100D', 4);
- Hint: It's okay to copy and paste your own code (but make sure you understand what it does)
Final Notes on Classes
Unlike function declarations, class declarations are not hoisted - they must be declared before using them to create objects.