Classes

Before we examine class, let's review. There are a few different ways to create objects.

Object Literal Notation

// Object Literal notation uses `var` and `:`
var instructor = { name: "Elie", age: 26};

// Or (notice the use of the keyword "new")
var instructor = new Object();

instructor.name = "Elie";
instructor.age = 26;

Problems with Object Literal Notation

Imagine you're an architect and you're tasked with designing a blueprint for a house (which will be used to build 25 similar looking houses). If we assume that every house has a number of square feet, bathrooms and bedrooms we can model this with a few objects.

var house1 = {
 sqFeet: 3000,
 bathrooms: 3,
 bedrooms: 2
}

var house2 = {
 sqFeet: 4000,
 bathrooms: 3.5,
 bedrooms: 2
}

var house3 = {
 sqFeet: 1000,
 bathrooms: 2,
 bedrooms: 1
}

var house4 = {
 sqFeet: 13000,
 bathrooms: 3.5,
 bedrooms: 7
}

Unfortunately, this is not very efficient. We've created 4 houses and already it's taken almost 20 lines of code. Fortunately we can create a class as our "blueprint" and then create objects based off of that.

Cookie Cutter Javascript
Figure: Cookie Cutter Javascript

Class Literal Notation

We can use a constructor function inside the class body to create multiple objects that share the same properties.

Using our previous example, we can create a class like this:

class House {
 constructor(sqFeet, bathrooms, bedrooms) {
    this.sqFeet = sqFeet;
    this.bathrooms = bathrooms;
    this.bedrooms = bedrooms;
 }
}

Notice that the word House is capitalized. This is to differ a class with any other normal variable. Also notice our use of the keyword this. Since we don't know what the value for the parameters will be, we use this as a placeholder. When we call the House function, we add in our values. To create an object instance using a constructor function, we use the new keyword. Here is an example of how we would create our four houses using a constructor function and the new keyword:

var house1 = new House(3000, 3, 2)
var house2 = new House(4000, 3.5, 2)
var house3 = new House(1000, 2, 1)
var house4 = new House(13000, 3.5, 7)

Class Method

So now we know that the main difference between class object and any other object is on its ability to own not only property, but also method. The term method here is a technical terms for functions that the object owned. This class object is also called instance.


class House {

 constructor(sqFeet, bathrooms, bedrooms) {
     this.sqFeet = sqFeet;
     this.bathrooms = bathrooms;
     this.bedrooms = bedrooms;
 }

 // we can also attach a method to this class like so
 expansion() { 
    // since it's still inside the class body, 'this' here refers to the House 'instance' 
    this.bathrooms++ 
    this.bedrooms += 2 
 }

 reduction() { 
    this.bathrooms-- 
    this.bedrooms -= 2 
 }
}

So attaching method is practically attaching a function into the object template. So whenever we create a new instance of that template, all the instance will have the methods prepared. It's now very simple to create this template structure thank to class notation. No more confusing terms to remember (prototype and constructor), we just need to remember how to create a class.

Now that we've attached a function into the class, now the function is owned by the instance. The only way for us to call function is through the object instance.

// this is incorrect way to call class method
// * assumption: class House has been created *

House.expansion() // TypeError: House.expansion is not a function
House.reduction() // TypeError: House.reduction is not a function

// the line above is wrong, because both methods are owned by House INSTANCE

var h1 = new House(200, 2, 2)
h1.expansion()

console.log(h1.bedrooms) // returns 4 because h1 is expanding

Points to note: instance !== class

Try it: Run the following code in the browser console, and expand each object. Look at the contents. Note that each object has its own version of the volume function, even though each copy does the same thing.

class Box {
    constructor(length, width, height) {
        this.length = length
        this.width = width
        this.height = height 
    }

    volume() { 
        console.log(this.length * this.width * this.height)
    }
}

var boxes = []

for (var i = 1; i <= 100; i++) { 
    boxes.push(new Box(i, i, i))
}

console.log(boxes) // array of BOX instances
console.log(boxes[5].volume()) // returns 216 (length: 6, width: 6, height: 6)

Things to watch for

  • Using the new keyword, Javascript does a few things:
    • Creates a new object
    • Attached the method property to the Class
  • When using the class method, don't try to call it without the new keyword.
    • Otherwise, you'll get the output of the constructor function, which is undefined. The new keyword will use the constructor to return a new object.
  • Always make sure the keyword this is on the left hand side: this.taco = taco. Remember, you're assigning parameters to properties of the new object being created.
  • return statements are usually unnecessary in constructors

results matching ""

    No results matching ""