Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

If you've been following along, you know that JavaScript is fundamentally based on prototypes. But let's be honest: writing prototype methods manually can feel clunky and visually messy. That's why ES6 gave us class. Now, it's important to realize that classes are mostly "syntactic sugar." They don't introduce a brand new object-oriented model to the language; they just give us a much cleaner way to write the prototype patterns we're already using.

Defining the blueprint for a SmartLight

Let's build something concrete. Imagine we're writing a system for a smart home. We need a way to create multiple light bulbs, each with its own state. Instead of creating a factory function, I'm going to use a class.

class SmartLight {
  constructor(roomName, brightness = 100) {
    this.roomName = roomName;
    this.brightness = brightness;
    this.isOn = false;
  }
}

const kitchenLight = new SmartLight('Kitchen');
const bedroomLight = new SmartLight('Bedroom', 50);

console.log(kitchenLight.roomName); // 'Kitchen'

The constructor is where the magic happens. It's the special method that runs the moment you call new SmartLight(). I've set a default value for brightness just in case we don't provide one—it's a small touch that makes the class much more flexible.

Adding behavior with methods

A light that can't actually turn on or off isn't very useful. In a class, we don't need to put our methods inside the constructor. We just define them directly in the class body.

class SmartLight {
  constructor(roomName, brightness = 100) {
    this.roomName = roomName;
    this.brightness = brightness;
    this.isOn = false;
  }

  turnOn() {
    this.isOn = true;
    console.log(`The ${this.roomName} light is now on.`);
  }

  turnOff() {
    this.isOn = false;
    console.log(`The ${this.roomName} light is now off.`);
  }
}

Fixing a common 'this' mistake

Here is where I usually trip up when I'm coding quickly. I wanted to add a toggle method to flip the light's state. I wrote it like this:

toggle() {
  isOn = !isOn; 
  console.log(`Toggled light to ${isOn}`);
}

When I ran this, it crashed with a ReferenceError: isOn is not defined. Why? Because I forgot that inside a class method, you must use the this keyword to access the instance's properties. JavaScript doesn't automatically know that isOn refers to the property on the current object; it thinks I'm looking for a global variable named isOn.

Here is the corrected version:

toggle() {
  this.isOn = !this.isOn;
  console.log(`Toggled light to ${this.isOn}`);
}

Specializing our light with inheritance

Now, let's say we want a fancy light that can change colors. We don't want to rewrite the turnOn and turnOff logic. This is where extends comes in. We can create a child class that inherits everything from SmartLight but adds its own specific features.

class ColorLight extends SmartLight {
  constructor(roomName, brightness = 100, color = 'white') {
    // super() calls the constructor of the parent class (SmartLight)
    super(roomName, brightness); 
    this.color = color;
  }

  changeColor(newColor) {
    this.color = newColor;
    console.log(`The ${this.roomName} light is now ${this.color}.`);
  }
}

const livingRoomLight = new ColorLight('Living Room', 80, 'blue');
livingRoomLight.turnOn(); // Inherited from SmartLight
livingRoomLight.changeColor('red'); // Specific to ColorLight

Notice the super() call. If you're extending a class and adding a constructor, you have to call super() before you touch this. It tells JavaScript to run the parent's setup logic first, ensuring the object is properly initialized before the child class adds its own custom properties.




📋 Practical Task

Build a SmartThermostat with Temperature Limits

Your task is to create a class system for a smart home thermostat. Follow these requirements:

  • Create a class called SmartThermostat.
  • The constructor should accept a roomName and an initialTemp.
  • Add a method setTemperature(newTemp) that updates the temperature and logs the change.
  • Create a child class called AdvancedThermostat that extends SmartThermostat.
  • The AdvancedThermostat should have a maxTemp property (set in its constructor).
  • Override the setTemperature method in AdvancedThermostat so that it refuses to set the temperature if newTemp exceeds maxTemp, logging a warning instead.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.