Home > Article > Web Front-end > Detailed explanation of prototype and prototype chain in JavaScript_Basic knowledge
Every object in JavaScript has a built-in attribute prototype. The explanation of the prototype attribute of an object in Javascript is: return a reference to the prototype of the object type. What this means is that the prototype attribute holds a reference to another JavaScript object that serves as the parent object of the current object.
Continue to read the analysis below:
Private variables and functions
Variables and functions defined inside a function cannot be accessed by the outside world if no interface is provided to the outside world, that is, the variables and functions are private to the function.
Static variables and functions
When a function is defined and the attributes and functions added by the dot "." are still accessible through the object itself, but its instances cannot be accessed, such variables and functions are called static variables and functions respectively. static function.
Instance variables and functions
In object-oriented programming, in addition to some library functions, we still hope to define some properties and methods at the same time when the object is defined, which can be accessed after instantiation. JS can also do this
Add new methods and properties for instance variables and methods
A and fn are modified in box1, but not changed in box2. Since arrays and functions are both objects and reference types, this means that although the properties and methods in box1 have the same name as those in box2, they have the same name. But it is not a reference, but a copy of the properties and methods defined by the Box object.
This is not a problem for attributes, but it is a big problem for methods, because the methods are doing exactly the same function, but they are copied twice. If a function object has thousands and instances method, then each instance of it must maintain a copy of thousands of methods, which is obviously unscientific. What can we do? Prototype came into being.
Basic concepts
Every function we create has a prototype attribute, which is a pointer to an object. The purpose of this object is to contain properties and methods that can be shared by all instances of a specific type. Then, prototype is the prototype object of the object instance created by calling the constructor.
The advantage of using prototypes is that object instances can share the properties and methods they contain. That is, instead of adding defining object information in the constructor, you can add this information directly to the prototype. The main problem with using constructors is that each method must be created in each instance.
In JavaScript, there are two types of values, primitive values and object values. Every object has an internal property prototype, which we usually call the prototype. The value of the prototype can be an object or null. If its value is an object, the object must also have its own prototype. This forms a linear chain, which we call the prototype chain.
Meaning
Functions can be used as constructors. In addition, only functions have the prototype attribute and can be accessed, but object instances do not have this attribute, only an internal inaccessible __proto__ attribute. __proto__ is a cryptic link in an object to the relevant prototype. According to the standard, __proto__ is not open to the public, which means it is a private property, but the Firefox engine exposes it as a public property that we can access and set externally.
When we call the Bro.run() method, since there is no such method in Bro, he will go to his __proto__ to find it, which is Browser.prototype, so the run() is finally executed. method. (Here, the first letter of a function in capital letters represents a constructor to distinguish it from ordinary functions)
When a constructor is called to create an instance, the instance will contain an internal pointer (__proto__) pointing to the prototype of the constructor. This connection exists between the instance and the prototype of the constructor, not between the instance and the constructor. .
Every JavaScript function has a prototype attribute. This attribute refers to an object, which is the prototype object. The prototype object is empty when initialized. We can customize any properties and methods in it, and these methods and properties will be inherited by the object created by the constructor.
So, now comes the problem. What is the relationship between constructors, instances and prototype objects?
The difference between constructors, instances and prototype objects
Instances are created through constructors. Once an instance is created, it has the constructor attribute (pointing to the constructor) and the __proto__ attribute (pointing to the prototype object),There is a prototype attribute in the constructor, which is a pointer pointing to its prototype object.
There is also a pointer (constructor attribute) inside the prototype object pointing to the constructor: Person.prototype.constructor = Person;
Instances can access properties and methods defined on the prototype object.
Here person1 and person2 are instances, prototype is their prototype object.
Another example:
It can be seen from the program running results that the methods defined on the prototype of the constructor can indeed be called directly through the object, and the code is shared. (You can try removing the prototype attribute in Animal.prototype.behavior and see if it still works.) Here, the prototype attribute points to the Animal object.
Array object instance
Look at an example of an array object. When we create the object array1, the actual object model of array1 in the Javascript engine is as follows:
The array1 object has a length attribute value of 3, but we can add elements to array1 through the following method:
Function object instance
What exactly does the new operator do? It’s actually very simple, it does three things.
Prototype Chain
Prototype chain: When calling a property or method from an object, if the object itself does not have such a property or method, it will go to its associated prototype object to look for it. If the prototype does not have one, it will go to the prototype association. Search for the predecessor prototype, and if there is no more, continue to search for the object referenced by Prototype.Prototype, and so on, until Prototype...Prototype is undefined (Object's Prototype is undefined), thus forming the so-called "prototype chain".
Here, a new entity is created using the constructor Shape(), and then used to override the prototype of the object.
Prototypal inheritance
Prototypal inheritance: At the end of the prototype chain, it is the prototype object pointed to by the prototype attribute of the Object constructor. This prototype object is the ancestor of all objects. This ancestor implements methods such as toString that all objects should inherently have. The prototypes of other built-in constructors, such as Function, Boolean, String, Date and RegExp, are all inherited from this ancestor, but they each define their own properties and methods, so that their descendants show the characteristics of their respective clans. Those characteristics.
In ECMAScript, the way to implement inheritance is to rely on the prototype chain.
Problems with the prototype chain: Although the prototype chain is very powerful and can be used to implement inheritance, it also has some problems. Chief among them comes from value prototypes containing reference types. Prototype properties containing reference types are shared by all instances; this is why properties are defined in the constructor rather than in the prototype object. When inheritance is implemented through prototypes, the prototype actually turns back into an instance of another type. As a result, the original instance properties become prototype properties.
When creating an instance of a subtype, parameters cannot be passed to the constructor of the supertype. In fact, it should be said that there is no way to pass parameters to the constructor of a supertype without affecting all object instances. Coupled with the problems just discussed due to the inclusion of reference type values in prototypes, prototype chains alone are rarely used in practice.
Another example:
Look at the following prototype chain example:
The __ptoto__ attribute (not supported by IE browser) is a pointer from the instance to the prototype object. Its function is to point to the prototype attribute constructor of the constructor. Through these two attributes, you can access the attributes and methods in the prototype. .
Object instances in Javascript are essentially composed of a series of attributes. Among these attributes, there is an internal invisible special attribute - __proto__. The value of this attribute points to the prototype of the object instance, an object. Instances only have a unique prototype.
The difference between __proto__ attribute and prototype attribute
Prototype is a proprietary attribute in the function object.
__proto__ is an implicit attribute of ordinary objects. When new is used, it will point to the object pointed to by prototype;
__ptoto__ is actually an attribute of an entity object, while prototype is an attribute belonging to the constructor. __ptoto__ can only be used in a learning or debugging environment.
Execution process of prototype mode
1. First search for the attributes or methods in the constructor instance, and if there is one, return it immediately.
2. If there is no instance of the constructor, look for it in its prototype object. If there is, return immediately
of the prototype object
Factory Mode
The factory pattern solves the problem of large amounts of duplication of instantiated objects, but there is another problem, that is, it is impossible to figure out which object they are instances of.
Using the constructor method not only solves the problem of repeated instantiation, but also solves the problem of object identification.
The difference between using the constructor method and the factory pattern is:
1. The constructor method does not display the created object (new Object());
2. Directly assign properties and methods to this object
3. No return statement
When the constructor is used and new constructor() is used, new Object() is executed in the background;
This in the function body represents the object produced by new Object()
1. To determine whether the property is in the instance of the constructor or in the prototype, you can use the `hasOwnProperty()` function
2. The way literals are created using the constructor attribute will not point to the instance, but to the Object. The way the constructor is created is the opposite
Why points to Object? Because Box.prototype = {}; this way of writing actually creates a new object.
Every time a function is created, its prototype will be created at the same time, and this object will also automatically obtain the constructor attribute
3. If it is an instance method, different instantiations have different method addresses and are unique
4. If it is a prototype method, then their addresses are shared