Constructor, Prototype, and Their Instance: Relationships
Tags: javascript, oop
Published: 2021-01-23 05:21:07

This article is going to use a relationship-oriented approach to dissect the prototypical OOP system of the .. *[the most popular programming language in the world](https://www.google.com/search?q=the+most+popular+programming+language+in+the+world)~*

Even if you're using the ES6 class syntax, that's just the surface, constructor and prototype are still doing their thing under the hood. So the prototypical system that I'll be talking about in this article is still relevant today and in the future.

The four relationships I'll get into are:
- An instance has a constructor
- An instance has a prototype
- A constructor has a prototype, a prototype has a constructor
- A prototype has a prototype (not in the picture)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5w4bqcrfst918h5kac4z.png)

(*has* means one thing *has a property pointing to* the other thing)

## 1. An instance has a constructor

This is a constructor:

```js
function Person(name){
  this.name = name
}
```
As you can see, it's basically just a function with a capitalized name.

And you can create new instances of this constructor like this:

```js
const a = new Person('andy')
```

Now this object `a` will have a `constructor` property that points back to the constructor `Person`.

```js
a.constructor === Person
```

Each object also has a `__proto__` property that points to a prototype. That means, the above object `a` also has a `__proto__` property that points to its prototype.

```js
a.__proto__
```

But first, let's talk about what a prototype is.

## 2. An instance has a prototype

A prototype is a place that holds the essential capabilities that the instances of a type can share. These capabilities are usually instance methods. 

If a method is called on an object, usually the method isn't stored in the object, it's stored in the object's prototype (or the prototype's prototype etc). All instances of a particular type will have their instance methods stored in the same prototype (or the prototype's prototype etc).

Let's get some hands-on.

Here's a string instance:

```js
const x = 'x'
```
(as a side note, a string is technically not an object, but when you access its methods, it gets converted into an object temporarily behind the scene, so for the scope of this article, we can just treat a string value as an object)

It has all the String type's capabilities, for example:

```js
x.toUpperCase()
```

It's getting these capabilities from `String.prototype`:

```js
x.__proto__ === String.prototype
```

(`__proto__` is a property that exists in all objects and values, it points to a prototype. However, `__proto__` is getting deprecated so it might not be available in some browsers, and definitely don't write code that relies on it.)

A cool thing about this is that, we can add new methods to this `prototype`:

```js
String.prototype.isX = function(){ 
  return this.toString() === 'x'
}
```
(This is just for illustration. In everyday development, don't add your own methods to built-in types such as String.)

And then this `isX` method will be magically available to our existing string value:

```js
x.isX() // true
```

This is how JavaScript's inheritance works. An object (an instance) gets its capabilities from another object (a prototype), which in turn might get its own capabilities from yet another object (that prototype's prototype).

This link between an instance and its prototype is automatically created when the instance is created, so usually you don't have to worry about connecting an object to a prototype.

## 3. A constructor has a prototype, a prototype has a constructor

Now let's talk about the relationship between constructor and prototype.

A constructor is linked to a prototype. And a prototype is linked to a constructor. They're like the yin and the yang of JavaScript's prototypical OOP.

Look at this:

```js
x.constructor.prototype.constructor.prototype.constructor.prototype
```

I can keep doing it, but I think you get the idea. There is a circular relationship between an object's constructor and its prototype. 

The constructor has a `prototype` property that points to its associated prototype, and the prototype has a `constructor` property that points to its associated constructor.

With that in mind, here are some interesting relationships:

```js
// the same constructor
x.constructor === String

// the same prototype
x.__proto__ === String.prototype
x.constructor.prototype === String.prototype
```

Just be aware that an instance has the `__proto__` property, a constructor has the `prototype` property. Their names are different, but they are pointing at the same prototype.

## 4. A prototype has a prototype

I mentioned "a prototype's prototype." This sounds complicated, but let's take a look at a simple example.

This will give you the prototype of a plain object:

```js
({}).__proto__
``` 

And This will give you the prototype of a string:

```js
''.__proto__
```

Obvious, they have different prototypes, so this should be `false`:

```js
({}).__proto__ === ''.__proto__
```

But since the `String` type is extending from the `Object` type. The plain object's prototype is actually the string's prototype's prototype.

So this will be `true`:

```js
({}).__proto__ === ''.__proto__.__proto__
```

This `__proto__.proto__` thing is called the *prototype chain*. And the end of the prototype chain is `null`.

## Bottom Line

Between a constructor and a prototype, that's a two-way relationship. Anything from an instance to either its constructor or its prototype, that's only a one-way relationship. There's no arrow pointing back to each instance from a constructor and a prototype.

Catch you later