Let’s take a look at this piece of code first:
Very simple A piece of code, let's see what exactly does this new do? We can split the new process into the following three steps:
<1> var p={}; In other words, initialize an object p.
<2> p.__proto__=Person.prototype;
<3> Person.call(p); In other words, constructing p can also be called initializing p.
The key lies in the second step, let’s prove it:
This code will return true. Explain that our step 2 is correct.
So what is __proto__? Let’s talk briefly here. Each object will initialize an attribute inside it, which is __proto__. When we access the attribute of an object, if this attribute does not exist inside the object, then he will go to __proto__ to find the attribute, this __proto__ It will have its own __proto__, so I keep looking for it, which is what we usually call the concept of prototype chain.
According to the standard, __proto__ is not open to the public, which means it is a private property, but the Firefox engine exposes it and makes it a common property that we can access and set externally.
Okay, the concept is clear, let’s take a look at the following code:
This paragraph The code is very simple, I believe everyone has written it like this, so let us see why p can access Person's Say.
First var p=new Person(); you can get p.__proto__=Person.prototype. Then when we call p.Say(), first of all, there is no Say attribute in p, so he needs to find it in his __proto__, which is Person.prototype, and we defined Person.prototype above. Say=function(){}; So, I found this method.
Okay, next, let’s look at something more complicated.
Let’s do this derivation:
var p=new Programmer() can get p.__proto__=Programmer .prototype;
And above we specified Programmer.prototype=new Person(); let’s split it like this, var p1=new Person();Programmer.prototype=p1; then:
p1.__proto__=Person.prototype;
Programmer.prototype.__proto__=Person.prototype;
According to the above, we get p.__proto__=Programmer.prototype. You can get p.__proto__.__proto__=Person.prototype.
Okay, after calculating clearly, let’s look at the above result, p.Say(). Since p does not have the attribute Say, we go to p.__proto__, which is Programmer.prototype, which is p1. Since there is no Say in p1, we go to p.__proto__.__proto__, which is Person.prototype. , so I found the alert("Person say") method.
The rest are the same.
This is the implementation principle of the prototype chain.
Finally, prototype is actually just an illusion. It only plays an auxiliary role in realizing the prototype chain. In other words, it only has a certain value when it is new, and the essence of the prototype chain actually lies in __proto__!