What Is _proto_ in JavaScript?
Have you ever noticed the _proto_ property while debugging some JavaScript code?
On my journey to learning JavaScript, I remember doing this and being quickly overwhelmed by the options displayed after expanding the _proto_
dropdown. That is why I’ve decided to explain the differences between _proto_
and prototype
, and how they relate to prototype inheritance.

Prototype Inheritance
To understand the mysterious _proto_
, we must begin by discussing JavaScript’s prototype inheritance. In JavaScript, objects can inherit properties and methods through the Object prototype.
An object prototype is an object that is automatically initialized when we declare a function. This object can then be used as a blueprint to declare methods and properties that will be automatically inherited by any objects created using that object’s constructor function.
All functions have a prototype, and at the highest level of the inheritance tree, we find JavaScript’s Object.prototype
. Think of the object prototype as the great-great-grandparent of all objects. Everything can be ultimately traced to the Object prototype. You can learn more by reading the official MDN documentation and you can refresh your object knowledge by reading this article, but for the purposes of this piece, we’ll be focusing on constructor functions, inheritance, and _proto_
.
So where does _proto_
fit into all of this?
Let’s go through an example to help us visualize what happens when we create a new object using a constructor function. Hopefully, this will all make sense by the end.
Creating a Constructor Function
Let’s create a constructor function:
We’re creating a function to create puppy instances. function Puppy(name) {
this.name = name
}*Our function name is capitalized as this standard practice, but it has no effect on code functionality.
As soon as we declare the function above, a prototype object is created for our Puppy
function. This prototype object is initialized with two properties:

- The original constructor function declared above.
- A reference to the
Object.prototype
through_proto_
.
I encourage you to open your console and try it out.
Creating a Puppy
Below, we're declaring a variable named toby
, creating a new Puppy
object, and passing it the name of toby
:
const toby = new Puppy(‘toby’);
When we create this new Puppy
object, the following happens behind the scenes:
- JavaScript creates an empty object.
- It creates the
_proto_
property as an additional property of our new object. This property is a direct reference to the constructor function’s property. - It evaluates the constructor function in our
Puppy
constructor function, and as a result of this keyword, it returns an object with the name property set totoby
. This object is then assigned to our constanttoby
.
Since we’re trying to understand _proto_
, I hope you’re following along and I encourage you to type the following on your console:
Object.getPrototypeOf(toby) === Puppy.prototype
//this will return true because our toby __proto__ references the Puppy prototype.toby.__proto__ === Puppy.prototype
//this comparison will also return true, but using the __proto__ is not recommended as it's been deprecated, and replaced by Object.getPrototypeOf(object name here). You can also set the prototype of an object with Object.setPrototypeOf(prototype name here), but this is not recommended due to the performance and compability issues this may create.
At this point, any changes that are made to our constructor function’s prototype will be reflected in the objects created using that function. Let’s see this in action below by adding a new method to our constructor’s prototype:
Puppy.prototype.bark = function() {return `WOOF! WOOF! I am a ferocious puppy named ${this.name} , fear me! `}
We can now call our bark
method on toby
. Our method will return the snippet below:

But what if we decide that toby
is super awesome and he has a very unique set of skills and a special bark. We can simply define a local method for toby
:
toby.bark = function() {
return `WOOOOOOOOOOOF! WOOOOOOF! I'm an awesome puppy named ${this.name}`
}
Now when we call toby.bark
, JavaScript will see that there’s a local bark method, so it will execute the local method instead of traversing up the prototype chain:

However, if toby
decided to change his bark style again, we could just delete the local bark
method and JavaScript will use the _proto_
reference in the toby
object and start going up the prototype chain looking for the bark
method once again. It will traverse the prototype chain and return our first example above.
If we deleted both bark
methods, JavaScript will traverse the prototype chain using the _proto_
references all the way back to JavaScript’s Object prototype. It does not have a bark
method or an additional _proto_
reference, and at that point, it will return null
.
You can verify this interesting fact by typing the code below on your console:

Object.getPrototypeOf(Object.prototype)
// This returns null because nothing else exists after the Object.prototype. The end of the road.
TLDR
_proto_
is a property that is automatically created in all JavaScript objects. This property references the prototype that created it.- A prototype is an object that is automatically created for all functions. This prototype can be used to declare methods and properties that will then be inherited by all objects created using that constructor function.
Object.prototype
is the parent object from which all other objects inherit.- This is a brief abstracted explanation of JavaScript inheritance. For a more in-depth explanation, check out the MDN docs.