Prototype and [[prototype]
On the premise of having a face object, let's look at a piece of code:
Copy codeThe Code is as follows:
// Animal Constructor
Function Animal (name ){
This. name = name;
}
// Animal prototype object
Animal. prototype = {
Id: "Animal ",
Sleep: function (){
Alert ("sleep ");
}
}
Var dog = new Animal ("wangcai ");
Alert (dog. name); // wangcai
Alert (dog. id); // Animal
Dog. sleep () // sleep
Its simple memory allocation structure:
Now let's explain the ins and outs of this memory diagram:
First, it is clear that [[prototype] and prototype are not the same thing.
Let's take a look at prototype. Each function object has a prototype attribute that is displayed. It represents the prototype of the object. More specifically, it represents a function object (constructor) the prototype of the created object. In this example, Animal. prototype is the prototype of dog. The object referenced by dog will inherit attributes and methods from the object referenced by Animal. prototype.
Each object has an internal attribute named [Prototype] pointing to its Prototype object. In this example, dog [[prototype] points to Animal. prototype. We all know that Animal. prototype is also an object. Even if it is an object, it must also have the [prototype] attribute pointing to the prototype object corresponding to it, thus forming a chain table structure, this is the concept of prototype chain. Additionally, different JS engine implementers can name the internal [[Prototype] attribute as any name and set its visibility, which is used only within the JS engine. Although the internal [[Prototype] cannot be accessed in the JS Code (FireFox is acceptable, the name is _ proto _ because Mozilla makes it public ), however, you can use the isPrototypeOf () method of the object for testing. Note that this method will be judged on the entire Prototype chain.
Note: The specific content of function objects will be described in the subsequent blog.
Attribute access principles
When you use obj. propName to access the attributes of an object, follow these steps (assuming that the internal [[Prototype] attribute of obj is named _ proto __):
1. If obj has the propName attribute, the property value is returned. Otherwise
2. If obj. _ proto _ is null, undefined is returned. Otherwise
3. Return obj. _ proto _. propName
The method of calling an object is the same as the process of accessing attribute search, because the function object of a method is an attribute value of an object.
Tip: the above step contains a recursive process, obj. _ proto _ is another object. Steps such as 1, 2, and 3 are also used to search for the propName attribute.
This is Prototype-based inheritance and sharing. The object1 method fn2 comes from object2. in concept, object2 overrides the object3 method fn2.
JavaScript objects should all be associated through the prototype chain. The top layer is the Object, that is, all objects are derived from the Object type.
In combination with the above theory, let's look at a more complex example. He clearly explained the main points of prototype, [[prototype], prototype chain, and attribute access:
Copy codeThe Code is as follows:
// Animal Constructor
Function Animal (name ){
This. name = name;
}
// Animal prototype object
Animal. prototype = {
Id: "Animal ",
Sleep: function (){
Alert ("sleep ");
}
}
Function Human (name, age ){
Animal. call (this, name );
This. age = age;
}
Human. prototype = new Animal ();
Human. prototype. id = "Human ";
Human. prototype. say = function (){
Alert ("hello everyone, My name is" + this. name + ", I'm" + this. age + "and I'm a" + this. id );
}
// Human-related call
Var jxl = new Human ('dump', 25 );
Alert (jxl. name); // dumb
Alert (jxl. id); // Human
Jxl. say (); // hello everyone, My name is stupid, I'm 25 and I'm a Human
Alert (Animal. prototype. isPrototypeOf (jxl); // true
Alert (Object. prototype. isPrototypeOf (jxl); // true
Based on the above Code, can you draw a memory diagram? Okay. Let's take a look:
Note: the root of prototype is Object. prototype, and the internal [[prototype] attribute of Object. prototype is null.
In fact, there are still many things to talk about here, but the principle is on this figure. You can try to adjust the code order, such as putting Human. prototype. id = "Human"; put it in Human. before prototype = new Animal ();, let's take a look at the running results and explain why and so on. You can learn a lot.
I found that it is perfect to show the internal running details of the program through memory!