Introduction

JavaScript is a prototype-based language, meaning object properties and methods can be shared through generalized objects that have the ability to be cloned and extended. This is known as prototypical inheritance and differs from class inheritance.

Before we get into inheritance let us venture into understanding prototypes

Prototype

When a function is created in JavaScript, the JavaScript engine adds a prototype property to the function. This prototype property is an object (called as prototype object) which has a constructor property by default. The constructor property points back to the function on which prototype object is a property.Every object in JavaScript has an internal property called [[Prototype]] We can demonstrate this by creating a new, empty object.

let newObect ={};

This also can be achieved by using object constructor like so

let newObject = new Object()

To find [[Prototype]] of this newly created object, we use object method getPrototypeOf()

Try this on the browser's console

Object.getPrototypeOf(newObject);

Output should be like so:

{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__..}

This also applies to primitive objects like e.g String, Numbers

Exercise

Use getPrototypeOf method to:

  • A number

  • A string

Constructor Function

Constructor functions are functions that are used to construct new objects. The new operator is used to create new instances based off a constructor function. We have seen some built-in JavaScript constructors, such as new Array() and new Date(), but we can also create our own custom templates from which to build new objects.

As an example, let’s say we are creating a very simple, text-based role-playing game. A user can select a character and then choose what character class they will have, such as warrior, healer, thief, and so on.

Since each character will share many characteristics, such as having a name, a level, and hit points, it makes sense to create a constructor as a template. However, since each character class may have vastly different abilities, we want to make sure each character only has access to their own abilities. Let’s take a look at how we can accomplish this with prototype inheritance and constructors.

To begin, a constructor function is just a regular function. It becomes a constructor when it is called on by an instance with the new keyword. In JavaScript, we capitalize the first letter of a constructor function by convention.

character.js

1
2
3
4
5
// Initialize a constructor function for a new Hero
function Hero(name, level) {
  this.name = name;
  this.level = level;
}

We have created a constructor function called Hero with two parameters: name and level. Since every character will have a name and a level, it makes sense for each new character to have these properties. The this keyword will refer to the new instance that is created, so setting this.name to the name parameter ensures the new object will have a name property set.

Now we can create a new instance with new.

let hero1 = new Hero('Bjorn', 1); If we console out hero1, we will see a new object has been created with the new properties set as expected.

Output Hero {name: "Bjorn", level: 1} Now if we get the [[Prototype]] of hero1, we will be able to see the constructor as Hero(). (Remember, this has the same input as hero1.proto, but is the proper method to use.)

Object.getPrototypeOf(hero1); Output constructor: ƒ Hero(name, level) You may notice that we’ve only defined properties and not methods in the constructor. It is a common practice in JavaScript to define methods on the prototype for increased efficiency and code readability.... // Add greet method to the Hero prototype Hero.prototype.greet = function () { return ${this.name} says hello.; }

You may notice that we’ve only defined properties and not methods in the constructor. It is a common practice in JavaScript to define methods on the prototype for increased efficiency and code readability.

We can add a method to Hero using prototype. We’ll create a greet() method.

character.js

1
2
3
4
5
...
// Add greet method to the Hero prototype
Hero.prototype.greet = function () {
  return `${this.name} says hello.`;
}

Since greet() is in the prototype of Hero, and hero1 is an instance of Hero, the method is available to hero1.

hero1.greet();

Output "Bjorn says hello."

Exercise

Create a file to do these:

  1. Create the constructor function for a Video object. The function should take in arguments of title (a string), uploader (a string, the person who uploaded it), and seconds (a number, the duration), and it should save them as properties of the object.

  2. Create a method on the Video object called watch(). When that method is called, it should use console.log to output a string like "You watched all 60 seconds of Otters Holding Hands!"

  3. Instantiate a new Video object and call the watch() method on it.

4.

Inheritance

prototypal inheritance

Remember inheritance in ruby where was class based i.e a classes inherits from the other.Well in Javascript there is another form inheritance where object inherit from another object.These objects are just like other objects in OO The object which we other object inherit from are forms the template and they are known as prototype prototypal inheritance supports the cloning of any object using an object linking mechanism.

Create a js file prototype.js and add the following code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Vehicle - parent
function Vehicle(name) { //  this a constructor function it is used to 
  this.name = name;
}
// parent method
Vehicle.prototype.start = function() {
  return "Engine of " + this.name + " starting…";
};

// Car - child
function Car(name) {
  Vehicle.call(this, name); // call super constructor.
}
// child extends parent
Car.prototype = Object.create(Vehicle.prototype);
// child method
Car.prototype.start = function() {
  console.log("Gidday! " + Vehicle.prototype.start.call(this));
};

// instances of child
var c1 = new Car("Infiniti G37");

// accessing the child method which internally access parent method
c1.start(); // outputs: "Gidday! Engine of Infiniti G37 starting…"
// Vehicle - parent
function Vehicle(name) {
  this.name = name;
}
// parent method
Vehicle.prototype.start = function() {
  return "Engine of " + this.name + " starting…";
};

// Car - child
function Car(name) {
  Vehicle.call(this, name); // call super constructor.
}
// child extends parent
Car.prototype = Object.create(Vehicle.prototype);
// child method
Car.prototype.start = function() {
  console.log("Gidday! " + Vehicle.prototype.start.call(this));
};

// instances of child
var c1 = new Car("Infiniti G37");

// accessing the child method which internally access parent method
c1.start(); // outputs: "Gidday! Engine of Infiniti G37 starting…"

The code above creates a parent constructor for a Vehicle and a method named start(). The Car object then inherits the start() method by passing the Vehicle's prototype to the Object.create() method. Its start() method overrides the parent's, while calling it from within the function body: Run it in the shell like so:

1
$ node prototype.js

Class and class inheritance

General syntax of a class in javascript is like so:

put these classes.js

1
2
3
4
5
6
7
class Person {
    constructor(name, age){
        this.age = age;
        this.name = name;

    }
}

The constructor method is a special method for creating and initializing an object created with a class. Though can always class without constructor.It is same to its ruby equivalent initialize.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Person {
  constructor(name, age) {
    this.age = age;
    this.name = name;
  }

  currentAge() {
    return `I am ${this.age} years old`;
  }
}


let person = new Person("Jane", 2)
console.log(person.currentAge())

Properties

Class basically consist of methods and properties.Properties are the the value Properties are a way to inject or retrieve data from an object.They create an abstraction over variables or data within a class.The main difference with the method represents action while the represent data.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Person {


    // constructor
    ...

    // static method

    totalWorkExperience(proffesionalYears){

      let otherJobs = 2
      return otherJobs  + proffesionalYears;
    }
}

In this case our property otherJobs.

static methods

Static methods are defined on the class itself, and not on the prototype.That means you cannot call a static method on the object (person), but on the class (Person).Think of them as class methods.

put these classes.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Person {
    // constructor
    ...

    static speech(){
        return "I can talk"
    }
}
// ..console logging person1
console.log(Person.speech);

class inheritance

Much like it's OO sisters javascript allow code resuse via class inheritance mechanism.The principle remain's the same the only difference is the keyword usage in this we usage of extends keyword.Let's say we want to create a class Youth which inherites from Person.

put these classes.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Person {
    // person class content
}
class Youth extends Person{
        constructor(hobby, age, name){
            super();
            this.name = name;
            this.age = age;
            this.hobby = hobby;
        }
}
let youth = Youth("hunting", 19, "Chris");
console.log(youth.currentAge());

Object youth(instance of class Youth) respond method currentAge even though it is not defined inside class Youth this is possible because it inherites from Person which has that method.The super keyword is used inside the constructor to refernce the super class(Person).

Private access

Even though it possible to inherit from a class we can limit what can be accessed by privatising access.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Class {

  // private property
  #x = 0;

  // private method (can only be called within the class)
  #incX() {
    this.#x++;
  }

  // private setter (can only be called within the class)
  set #setX(x) {
    this.#x = x;
  }

  // private getter (can only be called within the class)
  get #getX() {
    return this.$x;
  }

}

Exercise

  1. Create an object called shape that has the type property and a getType() method.

  2. Define a Triangle() constructor function whose prototype is shape. Objects created with Triangle() should have three own properties—a, b, and c, representing the lengths of the sides of a triangle.

  3. Add a new method to the prototype called getPerimeter().To the constructor function above.Its return value should perimeter of the rectangle