Skip to content

JavaScript Advanced (I) - Prototype to Prototype Chain

About 765 wordsAbout 3 min

javascript

2020-02-09

In the world of JavaScript, we often create an instance object through constructors:

function Person(name) {
  this.name = name
}
const person = new Person('Mark')
console.log(person.name) // Mark

We use the constructor Person to create an instance object person with new.

On the instance object person, there is a private property __proto__ that points to the prototype object prototype of its constructor,

So, what is prototype, what is __proto__?

Next, we start to get to the point.

prototype

In JavaScript, each function has a prototype property that points to the prototype object of the function.

function Person(name) {
  this.name = name
}
Person.prototype.age = 18

const person1 = new Person('Mark')
const person2 = new Person('John')
console.log(person1.name, person1.age) // Mark 18
console.log(person2.name, person2.age) // John 18

As you can see, when both person1 and person2 print the age attribute value is 18.

This is because Person.prototype is exactly the prototype of the instance objects person1 and person2.

Since prototype points to a prototype, then, what is prototype?

To a simple understanding, in JavaScript, when each object is created, there is another object associated with it, and this associated object refers to the prototype.

Warning

null has no prototype.

Objects inherit ** attributes from their prototype objects. This is why both person1 and person2 print the age attribute value is 18.

__proto__

In JavaScript, each object (except null) has a private property __proto__, This property points to the prototype of the object's constructor.

function Person(name) {
  this.name = name
}
const person = new Person('Mark')
console.log(person.__proto__ === Person.prototype) // true

At this point, you will find that since the constructor has a prototype prototype, the prototype is also an object, and the object has a prototype object that points to its constructor. So does the prototype object of the constructor also have its prototype object?

constructor

Before explaining the prototype, you need to understand a property on the prototype constructor, which points to the constructor associated with the prototype object:

function Person(name) {
  this.name = name
}
const person = new Person('Mark')
console.log(person.prototype.constructor === Person) // true

It helps us understand the constructor of the prototype.

Prototype of prototype

When we print and output Person.prototype.__proto__ in the console, we find that an object is printed:

function Person(name) {
  this.name = name
}
console.log(Person.prototype.__proto__)

output:

Person.prototype.proto

Since the prototype of Person also has a prototype, what is the constructor of the prototype object of this prototype?

We can use constructor to get its constructor:

function Person(name) {
  this.name = name
}
console.log(Person.prototype.__proto__.constructor)

output: Person.prototype.proto.constructor

You can find the prototype object of the prototype object of Person, and the constructor pointed to is Object.

That is, the prototype of Person.prototype points to Object.prototype.

So, does Object.prototype have its own prototype?

Object.prototype.proto

It can be found that the prototype of Object.prototype points to null.

And null means no object, it has no prototype.

Prototype Chain

Person.prototype -> Object.prototype -> null

(Consequently via __proto__)

This kind of object has a prototype object, and its prototype object has its prototype object, layer by layer, like a chain, and is called Prototype chain.

Almost all objects in JavaScript are instances of Object at the top of the prototype chain.

Tips

__proto__ is a non-standard attribute, but most browsers support accessing prototypes through this attribute.

__proto__ is an getter/setter accessor on Object in implementation. When using obj.__proto__, it can be understood that Object.getPrototypeOf(obj) is returned.

Inheritance based on prototype chain

The JavaScript object is a dynamic property "package" (referring to its own properties). The JavaScript object has a chain pointing to a prototype object. When trying to access an object's properties, it not only searches on the object, but also searches for the object's prototype and the prototype of the object's prototype, searching up layer by layer until it finds an attribute with a matching name or reaches the end of the prototype chain.

function Person(name) {
  this.name = name
}
Person.prototype.age = 18

const person1 = new Person('Mark')
const person2 = new Person('John')
console.log(person1.name, person1.age) // Mark 18
console.log(person2.name, person2.age) // John 18

In this example, although the instance object of Person does not have the age attribute itself, because its prototype object has the age attribute, The instance object inherits the attribute age from its prototype object. Therefore, the value of its age property is 18.