prototype and [[prototype]]
Based on the basics of face objects, let’s look at a piece of code:
//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
The corresponding simple memory allocation structure diagram:
Now let us explain the ins and outs of this memory diagram:
First of all, let’s be clear [[prototype]] and prototype are not the same thing.
Let’s look at prototype first. Each function object has a displayed prototype attribute, which represents the prototype of the object. More specifically, it represents the object created by the function object (constructor). prototype. Combined with this example, Animal.prototype is the prototype of dog, and the object referenced by dog will inherit properties and methods from the object referenced by Animal.prototype.
Each object has an internal property named [[Prototype]], which points to its corresponding prototype object. In this example, dog's [[prototype]] points to Animal.prototype. As we all know, Animal.prototype is also an object. Since it is an object, it must also have the [[prototype]] attribute pointing to its corresponding prototype. The object thus forms a linked list structure, which is the concept of the prototype chain. Extra: Different JS engine implementers can name the internal [[Prototype]] attribute to anything and set its visibility, and it will only be used inside the JS engine. Although the internal [[Prototype]] cannot be accessed in JS code (it can be accessed in FireFox, the name is __proto__ because Mozilla makes it public), you can use the object's isPrototypeOf() method for testing. Note that this method will be used throughout the Judgment is performed on the Prototype chain.
Note: The specific content of function objects will be explained in subsequent blog posts.
Attribute access principles When using obj.propName to access the properties of an object, follow the steps below (assuming obj’s internal [[Prototype]] property name is __proto__):
1. If obj has a propName attribute, return the value of the attribute, otherwise
2. If obj.__proto__ is null, return undefined, otherwise
3. Return obj.__proto__.propName
The method of calling an object is the same as the search process of accessing attributes, because the function object of the method is an attribute value of the object.
Tips: The above steps imply a recursive process. In step 3, obj.__proto__ is another object. Steps 1, 2, and 3 will also be used to search for the propName attribute.
This is inheritance and sharing based on Prototype. The method fn2 of object1 comes from object2. Conceptually, object2 overrides the method fn2 of object3.
JavaScript objects should all be related through the prototype chain. The top level is Object, that is, objects are all derived from the Object type.
Combining is the above theory, let us look at a more complex example, which clearly explains the relevant points of prototype, [[prototype]], prototype chain and attribute access:
//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 calls
var jxl = new Human('idiot',25);
alert(jxl.name);//idiot
alert(jxl.id);//Human
jxl.say();//hello ,My name is idiom,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 the corresponding memory map? Okay, let's take a look:
Note: The root of prototype is Object.prototype, and the internal [[prototype]] attribute of object Object.prototype is null.
Actually, there are There are many things that can be said, but the principles are all in this picture. You can try to adjust the order of the code, such as placing Human.prototype.id = "Human"; in Human.prototype = new Animal(); Earlier, you can learn a lot by looking at the running results and explaining why.
I found that it is really perfect to show the details of the internal operation of the program through memory!