JavaScript objects and how the Prototype works

Today I came across this amazing post from the Developers at Mozilla called “Re-Introduction to Javascript” that helped me better understand (I hope πŸ˜…) what are the object prototypes in JavaScript and how to use them πŸŽ†. But let’s have a look at an example to see this in action.

Object literals

In JavaScript everything that we define using { } is basically an Object. And defining an Object using the curly braces is actually defining what we call an Object literal. For example:

var john = {first: "John", last: "Doe"};
console.log(john);

Will produce the following output in the Console (in Google Chrome).

We can see that the Object has 2 properties of its own and everything else is included in the __proto__ section which means that it is inherited. And the inheritance path in this case is pretty sallow it goes from our Object to the JavaScript Object (we can see that in the constructor field).

Inheritance

Since we want to create more objects like the one we just did we want to find a way to define them that is more generic, which we will more easily able to extend in the future.

For this we are going to use a constructor function called Person defined like you see below and then we’ll create a new object and print it in the console.

function Person(first, last) {
    this.first = first;
    this.last = last;
}
var jane = new Person("Jane", "Doe");
console.log(jane);

Looking at the console output it is different now and we can see that there are 3 layers involved now. The first one is the actual properties of the object that we created, the second one is the 1st __proto__ which is the definition of the constructor that we created and the 3rd one is the 2nd __proto__ which is what comes with the Object definition of JavaScript.

Functions as object properties

Taking it a step further we can define functions as object properties and off course there are more than 1 ways of doing this in JavaScript πŸ˜‰.

1. As concrete properties of the object

This means that we can define these in the Person constructor function that we specified earlier thus changing it to look like this:

function Person(first, last) {
	this.first = first;
	this.last = last;
	this.fullName = function() {
		return this.first + ' ' + this.last;
	}
}
var jane = new Person("Jane", "Doe")
console.log(jane)
console.log(jane.fullName())

And if we have a look at the output in the console we will see that fullName has been defined in the property section of the object that we have just created and it will be defined in the that section for every single object that we create via our constructor.

The downside of that is that we have a lot of repetition of the code in the objects that we create but the plus side is that if we call this function JavaScript will only have to look into the properties of the top level object in order to find the function which makes the lookup faster.

2. As part of the constructor __proto__

This is the second case where instead of defining the function as a property of all the objects we add it as part of the constructor.

function Person(first, last) {
	this.first = first;
	this.last = last;
}
Person.prototype.fullName = function() {
  return this.first + ' ' + this.last;
}
var jane = new Person("Jane", "Doe")
console.log(jane)
console.log(jane.fullName())

In this case the function will still be accessible in the same way via the objects but it will appear in the __proto__ section.

Tip πŸ’‘: One thing to keep in mind in this case is that fullName is no longer a property of jane. This is something we can easily test in the two scenarios by using the following JavaScript method

console.log(jane.hasOwnProperty("fullName"))

In the first case this will print out true whereas in the second one it will print out false.

Leave a Reply