Search code examples
javascriptoopprototypeprototype-chain

What is "The" prototype?


I am trying to wrap my head around prototypes, and wold like to know what the prototype is exactly. Much of the confusion stems from not understanding the metalanguage used to describe prototypes.

Here is what I know:

When we create a named constructor function with properties inside it, the properties inside the body of that constructor function are inherited by object instances created by that constructor function. Here I've created an instance called person001 from the constructor function named Person.

function Person(firstName,lastName) {
    this.firstName = firstName;
    this.lastName = lastName
}
undefined
var person001 = new Person("John","Doe");

When I look at the object instance in the console and trace the prototype chain, I find it in 2 different places. It is a constructor object of the dunder proto object...

Person {firstName: "John", lastName: "Doe"}
firstName: "John"
lastName: "Doe"
__proto__:
constructor: ƒ Person(firstName,lastName)
__proto__: Object

and a property of the prototype object inside of the same constructor object.

Person {firstName: "John", lastName: "Doe"}
firstName: "John"
lastName: "Doe"
__proto__:
constructor: ƒ Person(firstName,lastName)
arguments: null
caller: null
length: 2
name: "Person"
prototype: 
constructor: ƒ Person(firstName,lastName)
__proto__: Object
__proto__: ƒ ()
[[FunctionLocation]]: script.js:76
[[Scopes]]: Scopes[1]
__proto__: Object

When I add a property using the .prototype property of the named constructor function, I am adding that property to the prototype object, NOT to the constructor function. The added property will sit alongside the constructor function in the object of the prototype property. Here I add a property called age using the prototype property of the constructor function Person.

Person.prototype.age = 0;  

So now that I've added an additional property, what exactly is the prototype?

When I run the Object.getPrototypeOf method on the object instance person001 it returns what looks to me like the prototype object. It has 3 properties -- a constructor function, the property I added, and the implicit dunder proto object.

Object.getPrototypeOf(person001);
{age: 0, constructor: ƒ}
age: 0
constructor: ƒ Person(firstName,lastName)
__proto__: Object 

So what is the prototype? Is it the prototype object {constructor function, additional properties}? Or is it just the constructor function of the prototype object?

Thanks in advance for your assistance.


Solution

  • When you do obj = new Person, there are three players in the game:

    • the freshly created object obj
    • the constructor function Person
    • the prototype, a special hidden object stored under Person.prototype

    The relationships between them are as follows:

    obj.__proto__ === Person.prototype
    
    Person.prototype.constructor === Person
    

    Illustration:

    function Person(firstName,lastName) {
        this.firstName = firstName;
        this.lastName = lastName
    }
    
    var person1 = new Person("John","Doe");
    var person2 = new Person("Ann","Smith");
    
    Person.prototype.age = 42;
    

    enter image description here