Classes and Objects: Building a JavaScript Universe!

Classes and Objects: Building a JavaScript Universe!

Picture yourself as the creator of a universe. Every planet you make has its own unique characteristics, like its size, color, and the speed at which it orbits its star. In the world of JavaScript, we can build and organize these planets using classes and objects.

In this article, we’ll take a detailed look at how object-oriented programming (OOP) in JavaScript allows us to create reusable, well-structured code by using classes and objects, much like crafting a universe of interconnected planets.


Objects – Your Cosmic Building Blocks

Before diving into classes, let’s start with objects, which are the building blocks of everything in JavaScript. An object is like a container that holds properties (data) and methods (functions) that represent the behavior of that object.

Let’s create a basic planet object:

code// A single planet represented as an object
const planet = {
    name: "Earth",
    size: "12,742 km",
    orbitSpeed: "29.78 km/s",
    spin() {
        console.log(`${this.name} is spinning.`);
    },
    orbit() {
        console.log(`${this.name} is orbiting at a speed of ${this.orbitSpeed}.`);
    }
};

planet.spin(); // Output: Earth is spinning.
planet.orbit(); // Output: Earth is orbiting at a speed of 29.78 km/s.

Explanation:

  • Properties: name, size, and orbitSpeed are attributes of the planet.

  • Methods: spin() and orbit() are actions (or behaviors) that the planet can perform.

  • this keyword: Refers to the current object (planet), allowing us to access properties like name or orbitSpeed from within methods.

But here’s the issue: if you wanted to create another planet like Mars, you’d have to manually rewrite the entire object. What if you wanted to create hundreds of planets? This is where classes come in—they allow us to easily create many objects that share the same structure.


Classes – The Blueprint for All Planets

A class is like a blueprint for creating objects. It’s a template that defines the properties and behaviors that all objects of that type will share. By using a class, you can create multiple objects (planets) with similar characteristics but different specific values (like name and size).

Think of a class as the cosmic blueprint for designing all the planets in your JavaScript universe. Each time you create a planet from this blueprint, you get a new instance of the class with its own unique properties.


Introducing the Constructor Method

When we create a new instance of a class, we need to set up that object’s properties (like its name, size, and orbitSpeed). This is done using the constructor method. The constructor is called automatically when a new object is created from the class.

Think of the constructor as a setup team that prepares each planet’s unique features right when it’s created.


Code Snippet: Creating the Planet Class with a Constructor

Here’s how you create a class in JavaScript, with a constructor to set up each planet’s properties:

class Planet {
    // Constructor method to set up properties
    constructor(name, size, orbitSpeed) {
        this.name = name;          // Assigns the 'name' property
        this.size = size;          // Assigns the 'size' property
        this.orbitSpeed = orbitSpeed; // Assigns the 'orbitSpeed' property
    }

    // Method for spinning
    spin() {
        console.log(`${this.name} is spinning.`);
    }

    // Method for orbiting
    orbit() {
        console.log(`${this.name} orbits at ${this.orbitSpeed}.`);
    }
}

Explanation:

  • Class definition: We create the Planet class using the class keyword.

  • Constructor method: The constructor is called every time a new planet is created. It takes in arguments (name, size, orbitSpeed) and assigns them to the object’s properties using this.

  • Methods (spin and orbit): Define actions that all planets can perform, such as spinning or orbiting.


What Happens When You Use new?

The new keyword is used to create an instance of a class (i.e., a new planet). This is like asking the cosmic 3D printer to produce a brand-new planet using the class blueprint.

Code Snippet: Creating a Planet with new

const earth = new Planet("Earth", "12,742 km", "29.78 km/s");
earth.spin(); // Output: Earth is spinning.
earth.orbit(); // Output: Earth orbits at 29.78 km/s.

Behind the scenes, here’s what happens:

  1. Memory Allocation: The new keyword creates a blank object in memory.

  2. Planet Constructor: The constructor function is called, and the object’s properties (name, size, orbitSpeed) are assigned specific values.

  3. this Binding: The this keyword inside the constructor refers to the new object being created. So, this.name = name assigns the passed value to the object’s name property.

  4. Prototype Link: The new object is linked to the prototype of the class, allowing it to inherit shared methods like spin() and orbit().

When we create earth, it’s an instance of the Planet class with its own unique values for name, size, and orbitSpeed.


Exploring Prototypes in Depth

When you create an instance of a class, it’s not just an independent object. It’s linked to the prototype of the class, which is like a shared storage space for methods. All instances created from the same class can share these methods, which saves memory and keeps your code efficient.

Let’s break it down:

  • Prototype: The prototype is an object that stores methods shared by all instances of the class. When you create an instance, it looks at the prototype to find methods like spin() or orbit() rather than storing them inside each object.

Checking the Prototype

You can see the prototype in action by checking it directly:

console.log(Planet.prototype); // Output: {constructor: f, spin: f, orbit: f}

This shows that the spin() and orbit() methods are part of the class prototype, not duplicated inside each planet instance. Instead, all planet instances inherit these methods from the prototype.


Expanding with Planet.prototype

If you want to add a new method to the class after defining it, you can add it directly to the prototype. Let’s add a describe() method to the Planet prototype:

Planet.prototype.describe = function() {
    console.log(`Planet: ${this.name}, Size: ${this.size}, Orbit Speed: ${this.orbitSpeed}`);
};

earth.describe(); // Output: Planet: Earth, Size: 12,742 km, Orbit Speed: 29.78 km/s

What’s happening:

  • We’re adding the describe() method to the Planet.prototype.

  • Now, every instance of Planet (like earth or any new planet) can use this method, but it doesn’t need to be defined inside every individual object. This makes the code more efficient.


Building a Solar System – Your Challenge

Now that you understand classes, instances, and prototypes, let’s put it all together in a fun challenge. You’ll build a solar system using the Planet class, and each planet will have its own unique properties.

Challenge Instructions:

  1. Create each planet: Use the Planet class to create objects for Mercury, Venus, and so on.

  2. Add custom properties: Give each planet its own size and orbit speed.

  3. Add methods: Use the spin() and orbit() methods, and add a custom describe() method to each planet to display its information.

Example:

const mercury = new Planet("Mercury", "4,880 km", "47.87 km/s");
const venus = new Planet("Venus", "12,104 km", "35.02 km/s");

mercury.describe(); // Output: Planet: Mercury, Size: 4,880 km, Orbit Speed: 47.87 km/s
venus.describe(); // Output: Planet: Venus, Size: 12,104 km, Orbit Speed: 35.02 km/s

You can expand on this by adding more behaviors or creating a full solar system with all the planets!


Flowchart: Class, Instances, and Prototypes

Here’s how the relationship between the class, instances, and prototype works:

    Planet Class          <-- Blueprint with properties and methods
         |
     [ Prototype ]        <-- Stores shared methods (spin, orbit, describe)
         |
    --------------------------
    |            |           |
[ Earth ]    [ Mars ]     [ Jupiter ]
 (Instance)   (Instance)   (Instance)

Each instance inherits its methods from the prototype, meaning shared behavior (like spin() or describe()) only needs to be stored in one place (the prototype) rather than being duplicated in every planet instance.


The Cosmic Power of Classes and Prototypes

In this first part, we’ve introduced Object-Oriented Programming in JavaScript, explored the basics of classes and instances, and examined the role of the prototype in sharing methods efficiently. Now you’re ready to use these tools to build entire universes of objects in your code!

In the next part, we’ll dive deeper into more advanced class concepts, such as inheritance and hierarchies, and expand our cosmic JavaScript universe even further.

Building Your Solar System – Creating a Cosmic Model

Now that we’ve explored how to create individual planets using classes and instances, it’s time to take it to the next level by building an entire solar system. Using the Planet class as a foundation, you can create multiple planets, each with unique properties, to form your cosmic model.

In this challenge, we’ll walk through how to model a solar system by creating multiple planet instances. You’ll be able to easily add planets, moons, and other celestial bodies using the same blueprint approach we’ve established.


Step 1: Setting Up Your Solar System

We’ll start by defining the core of our solar system: the Sun and the planets. For now, let’s stick with the planets, and we’ll create each planet as an instance of the Planet class.

// Creating the solar system planets
const mercury = new Planet("Mercury", "4,880 km", "47.87 km/s");
const venus = new Planet("Venus", "12,104 km", "35.02 km/s");
const earth = new Planet("Earth", "12,742 km", "29.78 km/s");
const mars = new Planet("Mars", "6,779 km", "24.07 km/s");
const jupiter = new Planet("Jupiter", "139,820 km", "13.07 km/s");
const saturn = new Planet("Saturn", "116,460 km", "9.69 km/s");
const uranus = new Planet("Uranus", "50,724 km", "6.81 km/s");
const neptune = new Planet("Neptune", "49,244 km", "5.43 km/s");

// Let's make these planets spin and orbit
mercury.spin(); // Output: Mercury is spinning.
venus.orbit();  // Output: Venus orbits at 35.02 km/s.

What’s happening here:

  • We’ve created individual planet instances using the Planet class, each with its own properties (name, size, and orbitSpeed).

  • The spin() and orbit() methods allow us to simulate their behavior in our JavaScript solar system.


Extending Your Solar System – Adding More Methods

In a solar system, planets do more than just spin and orbit. Let’s add a few more methods to the Planet class to make our planets more interactive. For example, we can add a describe() method that outputs all the details about a planet.

Code Snippet: Extending the Planet Class with More Methods

class Planet {
    constructor(name, size, orbitSpeed) {
        this.name = name;
        this.size = size;
        this.orbitSpeed = orbitSpeed;
    }

    // Method for spinning
    spin() {
        console.log(`${this.name} is spinning.`);
    }

    // Method for orbiting
    orbit() {
        console.log(`${this.name} orbits at ${this.orbitSpeed}.`);
    }

    // New method to describe the planet
    describe() {
        console.log(`Planet: ${this.name}, Size: ${this.size}, Orbit Speed: ${this.orbitSpeed}`);
    }
}

// Now, let’s create the planets again with the describe method
const earth = new Planet("Earth", "12,742 km", "29.78 km/s");
const mars = new Planet("Mars", "6,779 km", "24.07 km/s");

earth.describe(); // Output: Planet: Earth, Size: 12,742 km, Orbit Speed: 29.78 km/s
mars.describe();  // Output: Planet: Mars, Size: 6,779 km, Orbit Speed: 24.07 km/s

Explanation:

  • We’ve added a new describe() method that prints out the details of each planet. This helps provide a complete overview of any planet created using the Planet class.

  • Now, when we call earth.describe(), we get all of Earth’s properties in a neat, readable format.


Challenge – Build a Complete Solar System Model

Now that you’ve seen how to create planets, it’s time for you to expand your JavaScript universe by modeling the entire solar system. This will reinforce what we’ve learned about classes, instances, and methods. The challenge is to simulate a solar system with at least 8 planets, and to add unique properties and behaviors to each.

Challenge Instructions:

  1. Create each planet: Use the Planet class to model the 8 major planets (Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune) in the solar system.

  2. Customize properties: Give each planet its own unique size, orbit speed, and behavior.

  3. Extend the Planet class: Add additional methods, such as rotate() or isHabitable(), to create a richer solar system.

  4. Add moons: Feel free to add more celestial bodies like moons by creating a separate Moon class, following the same pattern as Planet.


Example: Adding Additional Methods to Planets

You can extend your solar system even further by adding a method to check whether a planet is habitable. This is especially relevant when modeling planets like Earth.

class Planet {
    constructor(name, size, orbitSpeed, isHabitable) {
        this.name = name;
        this.size = size;
        this.orbitSpeed = orbitSpeed;
        this.isHabitable = isHabitable; // New property to check habitability
    }

    spin() {
        console.log(`${this.name} is spinning.`);
    }

    orbit() {
        console.log(`${this.name} orbits at ${this.orbitSpeed}.`);
    }

    describe() {
        console.log(`Planet: ${this.name}, Size: ${this.size}, Orbit Speed: ${this.orbitSpeed}`);
    }

    checkHabitability() {
        if (this.isHabitable) {
            console.log(`${this.name} is habitable.`);
        } else {
            console.log(`${this.name} is not habitable.`);
        }
    }
}

// Creating Earth and Mars with habitability status
const earth = new Planet("Earth", "12,742 km", "29.78 km/s", true);
const mars = new Planet("Mars", "6,779 km", "24.07 km/s", false);

earth.checkHabitability(); // Output: Earth is habitable.
mars.checkHabitability();  // Output: Mars is not habitable.

Explanation:

  • We added a new property, isHabitable, which allows us to check whether a planet supports life.

  • The checkHabitability() method evaluates the isHabitable property and prints whether the planet is habitable or not.

Now you can create all sorts of planets with various behaviors and properties!


Class Structure for the Solar System

Here’s a flowchart to illustrate how the solar system is structured using the Planet class:

         Planet Class
         /   |   \    <-- Class definition with properties (name, size, orbitSpeed) and methods (spin, orbit, describe, checkHabitability)
       Earth Mars Jupiter
       (Instance) (Instance) (Instance)
         |        |       |
    (Habitable)  (Non-Habitable) (Gas Giant)

Each planet instance (like Earth, Mars, and Jupiter) has its own unique properties, but they all share the common behaviors defined in the Planet class, making it easy to expand and manage our cosmic model.


Conclusion – Creating Robust Code with Object-Oriented Principles

Through this cosmic journey, you’ve learned how to:

  1. Create reusable classes: We started by defining the Planet class to act as a blueprint for all planets in our JavaScript universe.

  2. Use instances to represent planets: We used the new keyword to create individual planets, each with its own unique properties.

  3. Extend classes with methods: By adding methods like describe() and checkHabitability(), you’ve learned how to expand class functionality to handle different tasks.

  4. Build a solar system model: You’ve now constructed a simple model of the solar system, complete with unique behaviors for each planet.

This approach of using classes and objects allows you to write clean, scalable, and reusable code that can easily grow and evolve—just like the universe!


Let’s explore Inheritance!

Now that we’ve built a universe with classes, it’s time to dive into inheritance. In the next article, we’ll explore how classes can share properties and behaviors, allowing you to model stars, moons, and other celestial bodies using inheritance.