• 10 hours
  • Easy

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 4/26/19

Understand object oriented programming

Log in or subscribe for free to enjoy all this course has to offer!

You've just learned how to create your first objects in JavaScript. This chapter will help you to better understand how to work with them.

Beyond cake

In the previous chapter, we created some cake code!

var cake = {
    flavor: "strawberry",
    levels: 2,
    price: "$10",
    occasion: "birthday",

    // Describe the cake
    describe: function () {
        var description = "The " + this.occasion + " cake has a " + this.flavor + " flavor, " + this.levels + " layers, and costs " + this.price + ".";
        return description;
    }
};

console.log(cake.describe());

// The cake is actually for a wedding!
cake.occasion = "wedding";

// Its number of layers and price both go up.
cake.levels = cake.levels + 8;
cake.price = "$50";

console.log(cake.describe());

Let's add some more pastries, as well as a "type" property to distinguish between multiple types of pastries.

var muffin = {
    type: "muffin",
    flavor: "blueberry",
    levels: 1,
    price: "$2",
    occasion: "breakfast",

    // Describe the pastry
    describe: function () {
        var description = "The " + this.type + " is a " + this.occasion + " pastry, has a " + this.flavor + " flavor, " + this.levels + " layers, and costs " + this.price + ".";
        return description;
    }
};

You'll notice that the cake code and muffin code are very similar. It'd make more sense for us to create a sort of pastry factory or bakery to create code for individual pastries, no?

Objects and prototypes in JavaScript

In addition to its special properties, every JavaScript object has an internal property called prototype . This is a link (known as reference ) to another object. When trying to access a property that does not exist in an object, JavaScript tries to find this property in the prototype of this object.

Here's an example.

var anObject = {
    a: 2
};

// Create anotherObject using anObject as a prototype
var anotherObject = Object.create(anObject);

console.log(anotherObject.a); // will show 2

Typing the above code into your chapter-8 JS file will result in the following browser outcome:

In this example, the JavaScript statement Object.create() is used to create the objectanotherObject  based on the prototype object anObject

If the prototype of an object does not have a desired property, then research continues in its own own prototype until we get to the end of prototype chain. If the property was found in objects, access returns the value undefined.

var anObject = {
    a: 2
};

// Create anotherObject using anObject as a prototype
var anotherObject = Object.create(anObject);

console.log(anotherObject.a); // will be 2
console.log(anotherObject.b); // will be undefined

This type of relationship between JavaScript objects is called delegation: an object delegates part of its operation to its prototype.

Cake prototype

Creating characters

Add the following code (type it manually, don't copy/paste!) to your course.js file for chapter 8.

var Pastry = {
    type: "",
    flavor: "",
    levels: 0,
    price: "",
    occasion: "",

    // Describe the pastry
    describe: function () {
        var description = "The " + this.type + " is a " + this.occasion + " pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
        return description;
    }
};

var muffin = Object.create(Pastry);
muffin.type = "muffin";
muffin.flavor = "blueberry";
muffin.levels = 1;
muffin.price = "$2";
muffin.occasion = "breakfast";

var cake = Object.create(Pastry);
cake.type = "cake";
cake.flavor = "vanilla";
cake.levels = 3;
cake.price = "$10";
cake.occasion = "birthday";

console.log(muffin.describe());
console.log(cake.describe());

The result is as follows:

In this example, we created an object named Pastry , which brings together the properties common to all the characters. The cake  and muffin  are created via  Pastry  as a prototype, which delegates its features to them.

Initializing objects

The process of creating a Pastry is a little repetitive: for each character, you must successively give a value to each of its properties. You can do better by creating an initialization function.

var Pastry = {
    // initialize the pastry
    init: function (type, flavor, levels, price, occasion) {
        this.type = type;
        this.flavor = flavor;
        this.levels = levels;
        this.price = price;
        this.occasion = occasion;
    },

    // Describe the pastry
    describe: function () {
        var description = "The " + this.type + " is a " + this.occasion + " pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
        return description;
    }
};

var muffin = Object.create(Pastry);
muffin.init("muffin", "blueberry", 1, "$2", "breakfast");

var cake = Object.create(Pastry);
cake.init("cake", "vanilla", 3, "$10", "birthday");

console.log(muffin.describe());
console.log(cake.describe());

The method init() takes the initial property values of the pastry as parameters. The pastry creation code is therefore reduced to only 2 steps:

  • The actual creation, with the  Pastry  object as a prototype,

  • The initialization of its properties, using the function init()  on the Pastry
     Object.

Baking the pastries

Pastries don't appear out of thin air, so you can introduce the idea of baking them.

var Pastry = {
    // initialize the pastry
    init: function (type, flavor, levels, price, occasion) {
        this.type = type;
        this.flavor = flavor;
        this.levels = levels;
        this.price = price;
        this.occasion = occasion;
    },

    // Describe the pastry
    describe: function () {
        var description = "The " + this.type + " is a " + this.occasion + " pastry, has a " + this.flavor + " flavor, " + this.levels + " layer(s), and costs " + this.price + ".";
        return description;
    },
    
    bake: function() {
        var baked = "The " + this.flavor + this.type + " was placed in the oven. It's done!"
    return baked
    }
};

var muffin = Object.create(Pastry);
muffin.init("muffin", "blueberry", 1, "$2", "breakfast");

var cake = Object.create(Pastry);
cake.init("cake", "vanilla", 3, "$10", "birthday");

console.log(muffin.bake());
console.log(cake.bake());
console.log(muffin.describe());
console.log(cake.describe());

Next level: make a game!

The baking example was relatively simple, but you can get as complicated as you like with this structure (defining objects, creating objects, doing things with them through a series of methods).

Let's go next-level now and look at an example with more significant interactions between objects. In this game, characters, players, and enemies are created. A player can attack an opponent, but the reverse is also true! If attacked, a character sees their life points decrease from the force of the attack. If a character's number of points reaches 0, then the character is eliminated. If the winner is a player, they receive a number of experience points equal to the value of the eliminated opponent.

Here are the associated object modeling. Read through it from beginning to end, line by line, and you may find it's less complicated than it first appears:

var Character = {
    // Initialize the character
    initCharacter: function (name, health, force) {
        this.name = name;
        this.health = health;
        this.force = force;
    },
    // Attack a target
    attack: function (target) {
        if (this.health > 0) {
            var damage = this.force;
            console.log(this.name + " attacks " + target.name + " and causes " + damage + " damage points");
            target.health = target.health - damage;
            if (target.health > 0) {
                console.log(target.name + " has " + target.health + " health points left");
            } else {
                target.health = 0;
                console.log(target.name + " has been eliminated!");
            }
        } else {
            console.log(this.name + " can't attack (they've been eliminated).");
        }
    }
};

var Player = Object.create(Character);
// Initialize the player
Player.initPlayer = function (name, health, force) {
    this.initCharacter(name, health, force);
    this.xp = 0;
};
// Describe the player
Player.describe = function () {
    var description = this.name + " has " + this.health + " health points, " +
        this.force + " force points " + this.xp + " experience points";
    return description;
};
// Fight an enemy
Player.fight = function (enemy) {
    this.attack(enemy);
    if (enemy.health === 0) {
        console.log(this.name + " eliminated " + enemy.name + " and wins " +
            enemy.value + " experience points");
        this.xp += enemy.value;
    }
};

var Enemy = Object.create(Character);
// Initialize the enemy
Enemy.initEnemy = function (name, health, force, species, value) {
    this.initCharacter(name, health, force);
    this.species = species;
    this.value = value;
};

// ...

Once modeled, the objects can then interact with one another through method calls:

// ...

var player1 = Object.create(Player);
player1.initPlayer("Rainbow Dash", 150, 25);

var player2 = Object.create(Player);
player2.initPlayer("Applejack", 130, 30);

console.log("Welcome to the adventure! Here are our heros:");
console.log(player1.describe());
console.log(player2.describe());

var monster = Object.create(Enemy);
monster.initEnemy("Spike", 40, 20, "orc", 10);

console.log("A wild monster has appeared: it's a(n) " + monster.species + " named " + monster.name);

monster.attack(player1);
monster.attack(player2);

player1.fight(monster);
player2.fight(monster);

console.log(player1.describe());
console.log(player2.describe());

Result of the above code:

Test with other initial values for health and force  properties, and you'll get different outcomes.

Example of certificate of achievement
Example of certificate of achievement