A shallow dive into the constructor property in Javascript

Before we get started, I would just like to make a couple disclaimers. First, I am a Launch School student and most of the information presented here has been based off of their curriculum. Second, I am by no means an expert in Javascript (I am a student!) so please bear that in mind! Okay let’s get started.

If you have been studying Object Oriented Programming with Javascript and have come from another language, you have probably noticed how confusing it can get and how much it differs from other languages. I am going to assume you have a basic understanding of Object Oriented Programming in Javascript, but if you don’t, an incredible video created by a fellow Launch School student, Ryan Schaul, is great resource to use to get familiar with what we are talking about today. I highly encourage watching it before moving on. Here is the video:

I want to use this article/blog post as a follow up to his amazing video to dive a little further into a constructor property because it can get very confusing very quickly.

Please note I will use __proto__ and [[Prototype]] interchangeably throughout. They refer to essentially the same thing and you can think of __proto__ as a public interface to access [[Prototype]].

To start, we should ask the question: Where can I find an object constructor property? Let’s imagine we have the following code:

Here from lines 1–3, we have created an object literal with one property (‘name’) and declared a variable (aneesh) to reference that object. We know from Ryan’s video that this object literal has a __proto__ property (essentially a getter method for it’s [[Prototype]] property), which refers to Object.prototype (which is an object itself). We can see from line 5 that calling the constructor property on aneesh returns Object (which, as it turns out is a function!), which makes sense because aneesh is an object. So when we call the constructor property on aneesh, where does Javscript actually find that property? Does the object referenced by aneesh contain it or does it have to look elsewhere? Let’s see using code:

Here, on line 6, we can see that the object referenced by aneesh does not have the property ‘constructor’ on it. So where does this property come from? We can see on line 7 that Object does not have it either. However, on line 8 we can see that Object.prototype contains it. This makes loads of sense! Since Javascript was unable to find a ‘constructor’ property on the aneesh object, it looked to it’s [[Prototype]] property and found the ‘constructor’ property in the object that the [[Prototype]] property on aneesh referenced, which was Object.prototype. Read that again, I know it can be hard to follow. Therefore, on line 9, we can see that the ‘constructor’ property on Object.prototype is the same return value we get when calling ‘constructor’ on aneesh. Let’s see this visually, using a similar style that Ryan used:

As we can see from this diagram, the object referenced by aneesh does not contain the ‘constructor’ property, but instead it is found after looking at the the object that aneesh’s __proto__ references, namely Object.prototype. So now we can clearly see where the constructor property is found. Notice how Object itself does not have a ‘constructor’ property. And when we call ‘constructor’ on Object we get Function. This is because Javascript will look through all of Object’s properties, not find a ‘constructor’ property, and then will look for it in the object that it’s __proto__ references, which is Function.prototype. Function.prototype has a ‘constructor’ property, which references Function and alas we have completed the journey!

So, now you are probably wondering what objects implicitly get a constructor property in Javascript? The answer may not be completely straightforward but it can be assumed that all Function objects will have a ‘prototype’ property, which refers to another object that will contain a ‘constructor’ property, which will usually point back to the Function object itself. We can further see this looking at the following code:

For now let’s just disregard the contents of the sayHi function declared here as it is irrelevant for our discussion. However, we can take note that sayHi is indeed a function. Therefore, according to the logic we just described it should have a ‘prototype’ property that should contain a constructor property that points back to the function (sayHi) itself. On line 16, we can see that the ‘prototype’ property on sayHi indeed contains a ‘constructor’ property. We can also make sure that sayHi contains the ‘prototype’ property and that the ‘constructor’ property on sayHi.prototype refers to sayHi itself:

Everything checks out! So let’s use our knowledge for one last example to really solidify our understanding. Examine the following code:

In this code, from lines 1–6 we created a Sponge object with a ‘species’ property and a ‘sayHi’ property referring to a function. On line 8, we used Object.create, which as we know from Ryan’s video, creates an empty object and sets it’s __proto__ ([[Prototype]]) property to the object passed as an argument into it (which in this case would the be the object referenced by Sponge). So at this point, spongebob is essentially an empty object that has a __proto__ property that refers to the object referenced by Sponge. From lines 9–11, we declare an ‘eat’ property on spongebob (the empty object) that refers to a function. We can see on line 13, that spongebob is able to access that property because it was explicitly declared on that object AKA the spongebob object itself contains the property ‘eat’. On line 14, we see that, even though the spongebob object itself does not contain the ‘sayHi’ property, Javascript looks at it’s __proto__, which points to the object referenced by Sponge and is able to find the ‘sayHi’ property on that object. On line 15, however, we see that calling ‘constructor’ on spongebob actually returns Object, rather than Sponge (which would make more logical sense to us). Why is that?

Well we know from before that the constructor property is only found in the object that the ‘prototype’ property of functions refers to. Since Sponge is not a function, it does not have a prototype property and also does not have a ‘constructor’ property. So when Javascript goes looking for a ‘constructor’ property on spongebob, it notices that spongebob itself does not have one. It then goes and looks at the the object that the __proto__ on spongebob refers to, which is Sponge because of line 8 (Object.create). Javascript will notice that Sponge also does not have a ‘constructor’ property and will then look at the object referred to by the __proto__ on Sponge, which is Object.prototype because Sponge is an object literal. Javascript will then find a ‘constructor’ property in the object referred to by Object.prototype and that ‘constructor’ property will point to Object itself, making our expression return ‘Object’. This is why when we use Object.create, we must manually define a ‘constructor’ property on the object that we pass into Object.create for our ‘constructor’ property to make logical sense. Here is a visual of this:

As we can see in the visual depiction above, we can explicitly define a ‘constructor’ property on Sponge itself that references Sponge so that any object created using Object.create (with Sponge being passed as an argument) will return Sponge when ‘constructor’ is called using the logic described.

I hope this makes the ‘constructor’ property and Object Oriented Programming in Javascript easier to understand and see mentally/visually. Please let me know if any of you have any questions or feedback. I would also, once again, like to commend Ryan Schaul for his video (linked above)! I know it really helped me and it is definitely worth a watch if you have not done so yet! Cheers!