Classes in JavaScript
In the last article, we introduced some basic concepts of object-oriented programming (OOP), and discussed an example where we used OOP principles to model professors and students in a school.
We also talked about how it's possible to useprototypes andconstructors to implement a model like this, and that JavaScript also provides features that map more closely to classical OOP concepts.
In this article, we'll go through these features. It's worth keeping in mind that the features described here are not a new way of combining objects: under the hood, they still use prototypes. They're just a way to make it easier to set up a prototype chain.
| Prerequisites: | Familiarity with JavaScript basics (especiallyObject basics) and object-oriented JavaScript concepts covered in previous lessons in this module. |
|---|---|
| Learning outcomes: |
|
In this article
Classes and constructors
You can declare a class using theclass keyword. Here's a class declaration for ourPerson from the previous article:
class Person { name; constructor(name) { this.name = name; } introduceSelf() { console.log(`Hi! I'm ${this.name}`); }}This declares a class calledPerson, with:
- a
nameproperty. - a constructor that takes a
nameparameter that is used to initialize the new object'snameproperty - an
introduceSelf()method that can refer to the object's properties usingthis.
Thename; declaration is optional: you could omit it, and the linethis.name = name; in the constructor will create thename property before initializing it. However, listing properties explicitly in the class declaration might make it easier for people reading your code to see which properties are part of this class.
You could also initialize the property to a default value when you declare it, with a line likename = '';.
The constructor is defined using theconstructor keyword. Just like aconstructor outside a class definition, it will:
- create a new object
- bind
thisto the new object, so you can refer tothisin your constructor code - run the code in the constructor
- return the new object.
Given the class declaration code above, you can create and use a newPerson instance like this:
const giles = new Person("Giles");giles.introduceSelf(); // Hi! I'm GilesNote that we call the constructor using the name of the class,Person in this example.
Omitting constructors
If you don't need to do any special initialization, you can omit the constructor, and a default constructor will be generated for you:
class Animal { sleep() { console.log("zzzzzzz"); }}const spot = new Animal();spot.sleep(); // 'zzzzzzz'Inheritance
Given ourPerson class above, let's define theProfessor subclass.
class Professor extends Person { teaches; constructor(name, teaches) { super(name); this.teaches = teaches; } introduceSelf() { console.log( `My name is ${this.name}, and I will be your ${this.teaches} professor.`, ); } grade(paper) { const grade = Math.floor(Math.random() * (5 - 1) + 1); console.log(grade); }}We use theextends keyword to say that this class inherits from another class.
TheProfessor class adds a new propertyteaches, so we declare that.
Since we want to setteaches when a newProfessor is created, we define a constructor, which takes thename andteaches as arguments. The first thing this constructor does is call the superclass constructor usingsuper(), passing up thename parameter. The superclass constructor takes care of settingname. After that, theProfessor constructor sets theteaches property.
Note:If a subclass has any of its own initialization to do, itmust first call the superclass constructor usingsuper(), passing up any parameters that the superclass constructor is expecting.
We've also overridden theintroduceSelf() method from the superclass, and added a new methodgrade(), to grade a paper (our professor isn't very good, and just assigns random grades to papers).
With this declaration we can now create and use professors:
const walsh = new Professor("Walsh", "Psychology");walsh.introduceSelf(); // 'My name is Walsh, and I will be your Psychology professor'walsh.grade("my paper"); // some random gradeEncapsulation
Finally, let's see how to implement encapsulation in JavaScript. In the last article we discussed how we would like to make theyear property ofStudent private, so we could change the rules about archery classes without breaking any code that uses theStudent class.
Here's a declaration of theStudent class that does just that:
class Student extends Person { #year; constructor(name, year) { super(name); this.#year = year; } introduceSelf() { console.log(`Hi! I'm ${this.name}, and I'm in year ${this.#year}.`); } canStudyArchery() { return this.#year > 1; }}In this class declaration,#year is aprivate field. We can construct aStudent object, and it can use#year internally, but if code outside the object tries to access#year the browser throws an error:
const summers = new Student("Summers", 2);summers.introduceSelf(); // Hi! I'm Summers, and I'm in year 2.summers.canStudyArchery(); // truesummers.#year; // SyntaxErrorNote:Code run in the Chrome console can access private elements outside the class. This is a DevTools-only relaxation of the JavaScript syntax restriction.
Private fields must be declared in the class declaration, and their names start with#.
Private methods
You can have private methods as well as private fields. Just like private fields, private methods' names start with#, and they can only be called by the object's own methods:
class Example { somePublicMethod() { this.#somePrivateMethod(); } #somePrivateMethod() { console.log("You called me?"); }}const myExample = new Example();myExample.somePublicMethod(); // 'You called me?'myExample.#somePrivateMethod(); // SyntaxErrorSummary
In this article, we've gone through the main tools available in JavaScript for writing object-oriented programs. We haven't covered everything here, but this should be enough to get you started. Ourarticle on Classes is a good place to learn more.
Next, we'll give you some tests that you can use to check how well you've understood and retained the information we've provided on Object-oriented JavaScript so far.