Chapter 6: Objects

6.3 Prototype

Next, let’s move on to prototypes.

In the previous section, we created two objects using the function constructor. Each object has a set of 5 properties and one method. The value for each property is different for the two objects. For instance, the value of the make property for petersCar is "Honda", while that for johnsCar is "Ford".

Besides these five properties, we also have a method called drive() in the constructor. In contrast to properties, the drive() method is the same for all the objects created.

When we put drive() in the constructor, all objects created will have a copy of the method each. In other words, we have two copies of the same method in our example. This is a waste of memory space.

Instead of doing it this way (i.e. putting the method in the object constructor), it is better to use what is known as a prototype.

prototype is a special property that every object in Javascript has by default. It associates the object with its constructor function and allows us to create functions and properties that are shared by all objects created by that constructor function.

Let’s see how this work. First, remove the drive() method from the constructor function in the previous section.

Next, add the following code to chap6.js (just after the CarObject() constructor function):

CarObject.prototype.drive = function(speed) { console.log("Moving forward at " + speed + " mph");};

In the statement above, we access the prototype property by writing

CarObject.prototype

Next, we attach the drive() method to the prototype by adding

drive = function(speed) { console.log("Moving forward at " + speed + " mph");};

Notice that this is essentially the same code that we had in the function constructor previously. The only difference is instead of prefixing this code with the this keyword, we prefix it with CarObject.prototype.

Now, refresh your browser to run the code again. You’ll see that everything runs as per normal; you still get the same output that you had in the previous section. The only difference is behind the scene, only one copy of the drive() method is created. Both objects (johnsCar and petersCar) have access to this method.

In addition to having prototype methods, objects can also have prototype properties. If all objects created by the constructor function share the same value for a particular property, we can add it to the prototype. For instance, suppose we want to store the number of wheels that a car has, we can add it to the prototype since all cars have four wheels. To do that, we write:

CarObject.prototype.wheels = 4;

Now, if you add

console.log(petersCar.wheels);

or

console.log(johnsCar.wheels);

to chap6.js, you’ll get 4 as the output for both cases.

Now, what if we need to change the value of a prototype? Suppose we want the drive() method of johnsCar to display the speed in kmph. Can we do that?

Yes. It is possible for us to override a prototype. For instance, we can update the drive() method for johnsCar by writing

johnsCar.drive = function(speed) {console.log("Moving forward at " + speed + " kmph");};

This only affects the drive() method for johnsCar, petersCar is not affected. You can verify this by writing

johnsCar.drive(80); 
petersCar.drive(80);

You’ll get

Moving forward at 80 kmph
Moving forward at 80 mph

as the output.