Analyze the javascript prototype and prototype chain, and analyze the javascript prototype
Each function we create has a prototype attribute, which is a pointer pointing to a prototype object, the attributes and methods in the prototype object can be shared by instances.
function Person(){}Person.prototype.name = "Nicholas";Person.prototype.age = 29;Person.prototype.sayName = function(){alert(this.name);};var person1 = new Person();person1.sayName(); //"Nicholas"var person2 = new Person();person2.sayName(); //"Nicholas"alert(person1.sayName == person2.sayName); //true
1. Understanding prototype objects
Whenever a new function is created, a prototype attribute is created for the function according to a set of specific rules. This attribute points to the prototype object of the function.
By default, all prototype objects automatically obtain a constructor attribute, which contains a pointer to the function of the prototype attribute.
After a constructor is called to create a new instance, the instance contains a pointer (internal attribute) pointing to the constructor's prototype object. In ECMA-262 5th, this pointer is called [Prototype].
Although there is no standard access to [[Prototype] in the script, Firefox, Safari, and Chrome support one attribute _ proto _ on each object. In other implementations, this attribute is completely invisible to the script.
However, it should be clear that this connection exists between the instance and the prototype object of the constructor, rather than between the instance and the constructor.
The previous example shows how to use the Person constructor and the Person. prototype code to create an instance. Figure 6-1 shows the relationship between objects.
Here, Person. prototype points to the prototype object, and Person. prototype. constructor points back to Person.
Both person1 and person2 contain an internal attribute that only points to Person. prototype. In other words, they have no direct relationship with constructors.
You can call person1.sayName (). This is achieved through the process of searching for object attributes. (The instance will be searched first. If the instance cannot be searched, the prototype will continue to be searched .)
Use the isPrototypeOf () method to determine the relationship between the instance and the prototype object
Alert (Person. prototype. isPrototypeOf (person1); // truealert (Person. prototype. isPrototypeOf (person2); // true
Return the prototype Object of the instance using the Object. getPrototypeOf () method.
Alert (Object. getPrototypeOf (person1) = Person. prototype); // true
The hasOwnProperty () method can be used to check whether an attribute exists in the instance or in the prototype.
Alert (person1.hasOwnProperty ("name"); // false prototype
Person1.name = "Greg ";
Alert (person1.name); // "Greg" -- from instance
Alert (person1.hasOwnProperty ("name"); // true
Ii. Simpler prototype syntax
In the preceding example, you must repeat Person. prototype for each attribute and method. To reduce unnecessary input and better visually encapsulate prototype functions, A more common approach is to overwrite the entire prototype object with an object literal containing all attributes and methods.
function Person(){}Person.prototype = { name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); }};
In the above Code, we set Person. prototype to be equal to a new object created in the form of an object literally. The final result is the same, but there is an exception: the constructor attribute no longer points to the Person.
As mentioned earlier, each time a function is created, its prototype object is created at the same time. This object also automatically obtains the constructor attribute.
var friend = new Person();alert(friend instanceof Object); //truealert(friend instanceof Person); //truealert(friend.constructor == Person); //falsealert(friend.constructor == Object); //true
Here, the instanceof operator test Object and Person still returns true, but the constructor attribute is equal to Object rather than Person.
If the constructor value is really important, you can set it back to the appropriate value as follows.
function Person(){}Person.prototype = { constructor : Person, name : "Nicholas", age : 29, job: "Software Engineer", sayName : function () { alert(this.name); }};
3. Native object prototype
All native reference types (Object, Array, String, and so on) define methods on the prototype of their constructor.
For example, the sort () method can be found in Array. prototype, and the substring () method can be found in String. prototype. Although this can be done, it is not recommended to modify the prototype of the native object.
Iv. Problems with prototype objects
The biggest problem with the prototype model is its shared nature. Modify one of them, and the other will also be affected.
function Person(){}Person.prototype = {constructor: Person,name : "Nicholas",age : 29,job : "Software Engineer",friends : ["Shelby", "Court"],sayName : function () {alert(this.name);}};var person1 = new Person();var person2 = new Person();person1.friends.push("Van");alert(person1.friends); //"Shelby,Court,Van"alert(person2.friends); //"Shelby,Court,Van"alert(person1.friends === person2.friends); //true
V. prototype chain
The basic idea is to use the prototype to inherit the attributes and methods of another reference type. Then the process is made up of instances and prototypes. This is the basic concept of prototype chain.
Function SuperType () {this. property = true;} SuperType. prototype. getSuperValue = function () {return this. property ;}; function SubType () {this. subproperty = false;} // inherits the SuperTypeSubType. prototype = new SuperType (); SubType. prototype. getSubValue = function () {return this. subproperty;}; var instance = new SubType (); alert (instance. getSuperValue (); // true
A graph description:
Property is located in SubType. prototype. This is because property is an instance property, while getSuperValue () is a prototype method. Since SubType. prototype is a SuperType instance, the property is in this instance.