Constructors - Functions that make Objects
Javascript doesn't have any special function that make them a constrcutor, the new
keyword does
all the work of making it behave like one. Conventionally, such function names are capitalised.
Creating Similar Objects
Friend and buddy objects have many similarities in terms of behaviour e.g. walk, talk, speak etc. But the data i.e. name, age etc is unique to them. With that we can create a constructor that creates this unique people with unique data and stores the common behaviour in its prototype object.
// constructor
function Person(name) {
// unique data
this.name = name
}
// common behavior
Person.prototype.greet = function () {
return 'Hello! I am ' + this.name
}
// create object with unique data
var friend = new Person('meher')
var buddy = new Person('you')
friend.greet() // > 'Hello! I am meher'
Inheritance between Constructors
There is no single step in JS that lets you create subclasses because JS was created differently. And subclassing is something that doesn't exist in prototype based languages but it can simulate one. So we need to do this manually and we need to get the following steps right in order to achieve the subclassing that exists in class-based languages.
- Inherit instance properties from the super class
- Inherit prototype properties from the super
instanceof
should work correctly for the instance objects
Setting up the Subclass
The first step to make the subclass inherit instance properties from the super class. And we do that
by invoking the super class using the call
method which basically executes the super function
using the this
of the subclass. If we used new
keyword here instead then we would have just
created an instance of the super class which we don't want.
function AwesomePerson(name, hobby) {
Person.call(this, name)
this.hobby = hobby
}
Linking the Subclass and Superclass Prototype
We have already seen how we can link the objects to share common behaviour. Its similar to that but
we need to note that Object.create
takes objects as inputs and therefore you would notice that we
pass super.prototype
instead of just super
as `super is a function.
AwesomePerson.prototype = Object.create(Person.prototype)
Out of curiosity, we can argue that why can't we do something like the following but the problem is
that this returns all the instance properties of the Person too, and for instance properties we have
already configured it previously when we did 'Person.call(this, name)'. And when it comes to setting
the prototype of AwesomePerson
, we just need the prototype object of the Person
.
AwesomePerson.prototype = new Person() // incorrect
Now, because we basically linked the prototype to Person, the constructor property on the
prototype
on AwesomePerson
points to Person
. So we fix that by following statement.
AwesomePerson.prototype.constructor = AwesomePerson
Now, we can go about adding methods on prototype of our AwesomePerson
function. Doing it before
the Object.create
step would get them overwritten.
AwesomePerson.prototype.express = function () {
return 'I love ' + this.hobby
}