In-depth understanding of the concept of JavaScript prototype
Prototype is a concept that is hard to understand in JavaScript, and there are many prototype-related attributes. The object has the "[prototype]" attribute, and the function object has the "prototype" attribute, the prototype object has the "constructor" attribute.
In order to understand the prototype and the relationship between these prototype attributes, this article is available.
I believe that through this article, we will be able to clearly understand the prototype. Now let's start the prototype journey.
Understanding prototype
Before starting the prototype introduction, let's first understand what prototype is?
In JavaScript,The prototype is also an object. The prototype can be used to inherit the attributes of an object,JavaScript objects contain an internal attribute [[Prototype], which corresponds to the Prototype of the object.
"[[Prototype]" is an internal attribute of an object and cannot be directly accessed. To facilitate viewing the prototype of an object, Firefox and Chrome provide the "_ proto _"Non-standardECMA introduces the standard Object prototype accesser "object. getPrototype (Object )").
Instance analysis
The following is an example of prototype concepts:
- function Person(name, age){
- this.name = name;
- this.age = age;
-
- this.getInfo = function(){
- console.log(this.name + " is " + this.age + " years old");
- };
- }
-
- var will = new Person("Will", 28);
In the above Code, a will object is created through the Person constructor. The following describes the prototype step by step through the object "will.
Step 1: view the prototype of the object "will"
The following code shows the prototype of the object "will:
- console.log(will.__proto__);
- console.log(will.constructor);
Result Analysis:
-
The "Person {}" object is the prototype of the object "will". It can be seen through Chrome expansion that "Person {}" serves as a prototype object, also, the "_ proto _" attribute corresponds to the prototype ).
-
The "constructor" attribute is also used in this Code.In JavaScriptPrototype objectIt also contains a "constructor" attribute, which corresponds to creating constructors for all instances pointing to the prototype..
-
Using the "constructor" attribute, we can determine whether an object is of the array type.
Function isArray (myArray ){
Return myArray. constructor. toString (). indexOf ("Array")>-1;
}
-
Here,The will object does not have the "constructor" attribute.However, by searching the prototype chain, find the "constructor" attribute of the prototype will. _ proto _) and obtain the Person function.
Step 2: view the prototype of the object will. _ proto _)
Since the prototype "Person {}" of will is also an object, we can also view the prototype of "will. _ proto ".
Run the following code:
- console.log(will.__proto__ === Person.prototype);
- console.log(Person.prototype.__proto__);
- console.log(Person.prototype.constructor);
- console.log(Person.prototype.constructor === Person);
Result Analysis:
-
First, check "will. _ proto _ = Person. prototype ",In JavaScript, each function has a prototype attribute. When a function is used as a constructor to create an instance, the prototype attribute value of this function will be assigned to all object instances as the prototype, that is, the _ proto _ attribute of the Instance). That is to say, the prototype attribute of all instances references the prototype attribute of the function.. After learning about the prototype attribute of the constructor, you must understand why the first sentence is true.
-
When "Person. prototype. when the _ proto _ "Statement gets the prototype of the will Object, it will get the" Object {} "Object, the prototype of all objects will be traced back to the "Object {}" Object.
-
For the "constructor" of the prototype object "Person. prototype", according to the previous introduction, the corresponding Person function will be used.
As shown above,The "Person. prototype" object and the Person function object use the "constructor" and "prototype" attributes to implement mutual reference. The following figure shows the relationship between the two objects).
Step 3: view the Object prototype
The previous part shows that the prototype of "will" is an Object. In JavaScript, all Object prototypes are traced back to the "Object {}" Object.
The following code shows the "Object {}" Object:
- console.log(Person.prototype.__proto__ === Object.prototype);
- console.log(typeof Object);
- console.log(Object);
- console.log(Object.prototype);
- console.log(Object.prototype.__proto__);
- console.log(Object.prototype.constructor);
The following code shows:
-
The Object itself is a function Object.
-
Since it is an Object function, there will certainly be the prototype attribute, so we can see that the value of "Object. prototype" is the prototype Object.
-
In turn, when you access the "constructor" attribute of the "Object. prototype" Object, you get the Obejct function.
-
In addition, when "Object. prototype. when _ proto _ "is used to obtain the prototype of the Object, it will get" null ", that is," Object {} "is the end point of the prototype chain.
Step 4: view the prototype of the object Function
In the above example, Person is a constructor, and in JavaScript the function is also an object. Therefore, we can also use the "_ proto _" attribute to find the prototype of the Person function object.
- console.log(Person.__proto__ === Function.prototype);
- console.log(Person.constructor === Function)
- console.log(typeof Function);
- console.log(Function);
- console.log(Function.prototype);
- console.log(Function.prototype.__proto__);
- console.log(Function.prototype.constructor);
Result Analysis:
-
In JavaScript, a Function Object is similar to an Object. This Object itself is a Function. The prototype _ proto _) of all functions, including functions and objects, is "Function. prototype ".
-
As a Function, the function object has the prototype attribute, which corresponds to the "Function () {}" object.
-
As an object, a Function object has the "_ proto _" attribute, which corresponds to the "Function. prototype ", that is," Function. _ proto _ = Function. prototype"
-
For the Function prototype Object "Function. prototype", the "_ proto _" attribute of the prototype Object corresponds to "Object {}"
Comparison between prototype and _ proto __
"Prototype" and "_ proto _" attributes may be mixed sometimes, "Person. prototype "and" Person. _ proto _ "is completely different.
Here we will briefly introduce "prototype" and "_ proto:
-
All objects have the _ proto _ attribute, which corresponds to the prototype of the object.
-
In addition to the _ proto _ attribute, function objects also have the prototype attribute,When a function is used as a constructor to create an instance, the prototype attribute value of the function is assigned to all object instances as a prototype, that is, the _ proto _ attribute of the instance is set)
Graphic example
Based on the instance analysis above, I believe you have learned a lot about the prototype.
However, we must be confused about the relationships in the above example. The prototype, the prototype, Function, Object, constructor, prototype, and so on are involved.
Now we will illustrate the results/relationships obtained from the analysis in the above example. I believe this figure will make you feel enlightened.
The summary is as follows:
-
All objects have the "_ proto _" attribute, which corresponds to the prototype of the object.
-
All function objects have the "prototype" attribute. The value of this attribute is assigned to the "_ proto _" attribute of the object created by the function.
-
All prototype objects have the "constructor" attribute, which corresponds to creating constructors for all instances pointing to the prototype.
-
Function objects and prototype objects are correlated through the "prototype" and "constructor" attributes.
Example of prototype Improvement
In the above example, the "getInfo" method is a member of the constructor Person. When two instances are constructed using the Person method, each instance contains a "getInfo" method.
Var will = new Person ("Will", 28 );
Var wilber = new Person ("Wilber", 27 );
As we have learned before, the prototype is to facilitate property inheritance, so we can regard the "getInfo" method as the Person prototype Person. _ proto _), so that all instances can use the "getInfo" method through prototype inheritance.
Modify the example as follows:
- function Person(name, age){
- this.name = name;
- this.age = age;
- }
-
- Person.prototype.getInfo = function(){
- console.log(this.name + " is " + this.age + " years old");
- };
The modified result is:
Prototype chain
Because each object and prototype have a prototype, the prototype of the object points to the parent of the object, and the prototype of the parent points to the parent. This prototype is connected to form a prototype chain.
In the article "understanding the scope chain of JavaScript", we have introduced how to search for identifiers and attributes through the scope chain and prototype chain.
Here we will continue to look at the property search based on the prototype chain.
Attribute search
When you look for an Object's properties, JavaScript will traverse the prototype chain up until the property of the given name is found until the search reaches the top of the prototype chain, that is, "Object. prototype). If the specified property is still not found, the undefined is returned.
Let's look at an example:
- function Person(name, age){
- this.name = name;
- this.age = age;
- }
-
- Person.prototype.MaxNumber = 9999;
- Person.__proto__.MinNumber = -9999;
-
- var will = new Person("Will", 28);
-
- console.log(will.MaxNumber);
- // 9999
- console.log(will.MinNumber);
- // undefined
In this example, give "Person. prototype "and" Person. _ proto _ "added the" MaxNumber "and" MinNumber "attributes for the two prototype objects. The difference between" prototype "and" _ proto _ "needs to be clarified here.
"Person. prototype "corresponds to the prototype of all instances constructed by Person, that is," Person. prototype "is part of the prototype chain of these instances, so when these instances perform attribute search, it will reference" Person. properties in prototype.
Hide attributes
When you search for an attribute through the prototype chain, you first find the attribute of the object. If you cannot find the attribute, you can continue to search for the attribute based on the prototype chain.
In this way, if we want to overwrite some attributes on the prototype chain, we can directly introduce these attributes in the object to achieve the property hiding effect.
Let's look at a simple example:
- function Person(name, age){
- this.name = name;
- this.age = age;
- }
-
- Person.prototype.getInfo = function(){
- console.log(this.name + " is " + this.age + " years old");
- };
-
- var will = new Person("Will", 28);
- will.getInfo = function(){
- console.log("getInfo method from will instead of prototype");
- };
-
- will.getInfo();
- // getInfo method from will instead of prototype
How objects are created affects the prototype chain.
In the example at the beginning of this article, the will object is created through the Person constructor. Therefore, the prototype of "will" is "Person. prototype ".
Similarly, we can create an object using the following method:
- var July = {
- name: "July",
- age: 28,
- getInfo: function(){
- console.log(this.name + " is " + this.age + " years old");
- },
- }
-
- console.log(July.getInfo());
When an Object is created in this way, the prototype chain becomes. The prototype of the July Object is "Object. prototype", that is, the Object construction method affects the form of the prototype chain.
HasOwnProperty
"HasOwnProperty" is "Object. prototype, which can determine whether an object contains custom attributes rather than attributes on the prototype chain, because "hasOwnProperty" is the only function in JavaScript that processes attributes but does not search for the prototype chain.
I believe you still remember that in the first example of this article, we can access the "constructor" attribute through will and get the will constructor Person. Here we can use the "hasOwnProperty" function to see that the will object does not have the "constructor" attribute.
The following output shows that "constructor" is the prototype of "will. _ proto _), but by searching the prototype chain, the will object can discover and use the "constructor" attribute.
Another important application scenario of "hasOwnProperty" is to traverse the attributes of an object.
- function Person(name, age){
- this.name = name;
- this.age = age;
- }
-
- Person.prototype.getInfo = function(){
- console.log(this.name + " is " + this.age + " years old");
- };
-
- var will = new Person("Will", 28);
-
- for(var attr in will){
- console.log(attr);
- }
- // name
- // age
- // getInfo
-
- for(var attr in will){
- if(will.hasOwnProperty(attr)){
- console.log(attr);
- }
- }
- // name
- // age
Summary
This article introduces the concepts related to the original JavaScript model. The prototype can be summarized as follows:
-
All objects have the [[prototype] attribute accessed through _ proto _. This attribute corresponds to the object's prototype.
-
All function objects have the "prototype" attribute. The value of this attribute is assigned to the "_ proto _" attribute of the object created by the function.
-
All prototype objects have the "constructor" attribute, which corresponds to creating constructors for all instances pointing to the prototype.
-
Function objects and prototype objects are correlated through the "prototype" and "constructor" attributes.
We also need to emphasize the example at the beginning of the article and the relationship between a "common object", "function object", and "prototype object" obtained through the example, when you are confused about the relationship of the prototype, you can think about this figure or re-draw a diagram of the current object) to clarify the complex relationship.
Through these introductions, I believe we can have a clear understanding of the prototype.