Inheritance using Constructor.prototype

In the previous lesson we learnt how to write methods like this:

function Person(name) {
  this.name = name;
  this.greeting = function greeting() {
    alert('Hello my name is ' + this.name);
  }
}

Using this approach, every time that Person is instantiated, a new greeting function is created. If you create a new Person() 100 times, 100 greeting functions will be created for each one. This seems wasteful considering all the greeting functions are exactly the same.

One way to solve this is using prototypal inheritance. That sounds a bit scary so let's take it a step at a time.

We can say that a property is inherited when it is passed down from a parent. For example, perhaps one of the properties your parents passed to you was being really good looking. You might say that it's a family trait.

In JavaScript, there are 2 ways that a new objects receives properties. The first is copying, the way we've being doing it so far: inside the constructor function properties are added to the new object (this) when it is created. The properties are inherited from the (parent) constructor function, but once the object has been created the constructor function cannot change it.

prototype

The other way that objects can receive properties from their constructor function is by inheritance. This happens via the constructor function's prototype, which is an object containing hidden properties and methods.

Exercise

Open up the console in your web browser and type in String.prototype. An object with will be returned. If you expand this object you'll see that it contains several hidden methods.

You can also search on the internet for "String prototype", "Array prototype" etc. and find documentation for the associated methods.

When you create a new object, a hidden link is made between the new object and it's constructor function's prototype.

We can test that this link exists in our browser's console:

function MyConstructor () {}
var myObj = new MyConstructor();
Object.getPrototypeOf(myObj) === MyConstructor.prototype; // true

Let's add a method to our constructor function's prototype:

MyConstructor.prototype.greeting = function () {
  console.log('Hello');
}

The greeting method will now be inherited by objects created with MyConstructor.

var myObj2 = new Constructor();
myObj2.greeting(); // Hello

Remember that when objects are created a link between them and their constructor is created? Well, even though myObj was created before we added the greeting method, myObj is linked to MyConstructor.prototype, so it will inherit the newly created method as well.

myObj.greeting(); // Hello

Both myObj and myObj2 inherit properties from MyConstructor via prototypal inheritance.

Object.getPrototypeOf(myObj) === Object.getPrototypeOf(myObj2) === MyConstructor.prototype; // true

The prototype chain

When you access a property of an object, JavaScript first checks if the object has such a property itself. If it does it will use that. If not, it will check the object's prototype.

function Person (name, formal) {
  this.name = name;
  if (formal) {
    this.greeting = function () {
      console.log('Hello, my name is ' + this.name);
    }
  }
}

Person.prototype.greeting = function () {
  console.log('Hey, it\'s ' + this.name);
}

var alice = new Person('Alice');
// No greeting method on alice
console.log(alice); // { name: 'Alice' }
alice.greeting(); // Hey it's Alice

var bob = new Person('Bob', true);
// bob was instantiated with a greeting method
console.log(alice); // { name: 'Bob', greeting: function() {} }
bob.greeting(); // Hello, my name is Bob

results matching ""

    No results matching ""