Explain JS prototype and prototype chain in detail

content

1. Constructor prototype prototype

2. Object prototype __proto__

3.constructor constructor

4. Prototype chain

5. This in the prototype object points to

6. Extending built-in objects (application of prototype objects)


Before ES6, we implemented object orientation through constructors. We put the public properties and methods of the object in the constructor

like this:

function student(uname,age) {
    this.uname = uname;
    this.age = age;
    this.school = function() {
        console.log('深圳理工大学');
    }
}
var stu1 = new student('小红',18);
var stu2 = new student('小紫',20);

However, although the constructor method is easy to use, it has the problem of wasting memory. For example, in the above example, we have a function in the constructor. The function is a complex data type, and it will create a separate space in memory. Here we create two instantiated objects, then two memory spaces will be opened to store the same function, which will cause the problem of memory waste.

1. Constructor prototype prototype

The function that the constructor assigns via the prototype is shared by all objects .
JavaScript stipulates that every constructor has a prototype property that points to another object. Note that this prototype is an object, and all properties and methods of this object will be owned by the constructor.
We can define those invariant methods directly on the prototype object, so that all object instances can share these methods.
So in the above example, we can put the public function in the prototype object, so that there will be no memory waste

function student(uname,age) {
    this.uname = uname;
    this.age = age;
}
student.prototype.school = function() {
    console.log('深圳理工大学');
}
var stu1 = new student('小红',18);
var stu2 = new student('小紫',20);

Then we understand what the prototype is, he is an object, we call the prototype the prototype object

What is the role of the prototype? Four words, sharing method

2. Object prototype __proto__

The object will have an attribute __ proto__ that points to the prototype prototype object of the constructor. The reason why our object can use the properties and methods of the prototype prototype object of the constructor is because the object has the _ proto_ prototype.
On the object, the system itself adds a __proto__ pointing to the prototype object of our constructor, so the __proto__ object prototype and the prototype object prototype are equivalent.

Let's verify and see what will be output:

console.log(stu1.__proto__ === student.prototype);

 The final output is true to prove that the object prototype __proto__ and the prototype object protptype are equivalent

Therefore, the search rule for methods is to first check whether there is a school method on the stu1 object. If so, execute the school method on this object. If there is no school method, because there is __proto__, go to the constructor prototype object prototype to find it. school this method

If you still don’t understand, here is a picture to understand your question:

3.constructor constructor

Object prototype (__proto__) and constructor (prototype) There is a property constructor property in the prototype object. The constructor is called the constructor function because it points back to the constructor function itself.

Let's print student.prototype and stu1.__type__ to see if the constructor property exists:

console.log(student.prototype);
console.log(stu1.__proto__);

 You can see that there are constructors here, so what does the constructor do?

Constructor is mainly used to record which constructor the object refers to, it can make the prototype object re-point to the original constructor

We know that we can define those public methods in the prototype object, but if there are many public methods, it is much more convenient for us to store them in the form of objects:

student.prototype = {
    school:function() {},
    location:function() {}
}

Then we output the constructor of the prototype object to see if there is any change:

console.log(student.prototype.constructor);
console.log(stu1.__proto__.constructor);

The final output is this:

 Why is this, shouldn't the constructor point to our student constructor?

Because we are adding methods to the prototype object through student.prototype.school, but we just assigned assignments, which overwrites everything in the original prototype, so student.prototype has no constructor. Without a constructor, it naturally means Can't go back to the student constructor

At this time, we need to manually use the constructor attribute to point back to the original constructor

student.prototype = {
    constructor:student,
    school:function() {},
    location:function() {}
}

Let's output the constructor of the prototype object again:

 This way we know which constructor the object was created by.

Now let's update the relationship diagram among constructors, instances, and prototype objects:

4. Prototype chain

Because the student prototype object is also an object, we said earlier that as long as it is an object, there is an object prototype.

Then we print the prototype object to see if there is a prototype in it:

function student(uname,age) {
    this.uname = uname;
    this.age = age;
}
student.prototype.school = function() {
    console.log('深圳理工大学');
}
var stu1 = new student('小红',18);
console.log(student.prototype);

Output result:

It can be seen that there is also a prototype in the prototype object, and because the prototype points to the prototype object, then who does the __proto__ in our student.prototype point to?

Let's print:

console.log(student.prototype.__proto__);

You can see that the constructor points to the Object prototype object.

Who created the Object prototype object, no doubt created by the Object constructor. So let's continue, the Object prototype object is also an object, so it also has a prototype, and who does this prototype point to?

Let's output:

console.log(Object.prototype.__proto__);

The final result is empty:

This brings us to the top level, so we can string these together to get a prototype chain:

5. This in the prototype object points to

We know that this in the constructor refers to the object instance, so in the function in the prototype object, who does this in this function point to?

 We declare a global variable that, assign this in the prototype object to that, and see if the that points to an instance object:

function student(uname,age) {
    this.uname = uname;
    this.age = age;
}
var that;
student.prototype.school = function() {
    that = this;
    console.log('深圳理工大学');
}
var stu1 = new student('小红',18);
stu1.school();
console.log(that === stu1);

Output result:

So this in the prototype object function also points to the instance object stu1 

6. Extending built-in objects (application of prototype objects)

We can extend and customize the original built-in object through the prototype object. For example, adding a custom sum function to an array

Let's output the prototype object of the array to see what methods are in it:

console.log(Array.prototype);

There is no custom summation function for the array here, so we add this method to the prototype object of the array:

Array.prototype.sum = function() {
    var sum = 0;
    for(var i = 0;i<this.length;i++)
    {
        sum += this[i];
    }
    return sum;
}
var ss = new Array(4,5,3,6);
console.log(ss.sum());

In our custom sum method, this.length refers to the length of the array that calls this method, because in the previous section we know that this in the prototype object function also points to the instance object

We create an array instance object through the new method, we add the sum method to the prototype object of the array, then our instance object can call it.

Output result:

Let's print the prototype object of the array again to see if there is a sum method in it:

It can be seen that sum is successfully added to the prototype object of the array, so that when we continue to use the sum of the array, we can directly call the sum method.

Guess you like

Origin blog.csdn.net/qq_49900295/article/details/123953725
Recommended