Recently, when I was learning JavaScript and learning the prototype of js object-oriented, I have a lot of insights. If there is something wrong, I hope it can be corrected.
As an object-oriented language, js naturally has the concept of inheritance, but there is no concept of classes in js, so there is no extends similar to those in java. Therefore, I think inheritance in js mainly depends on prototypes (chains) in js.
So, what is the prototype? We know that functions in js are also an object. When we create a function, the function actually has a property called prototype. This genus type is called a prototype property. It is a pointer that points to the prototype object of this function. This prototype object has a default property called constructor. This genus type points to a function that has a prototype type.
function Person(){} Person.prototype={ // constructor:Person; first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatting");} };Taking this as an example, we first created a function Person. This function has a default attribute prototype, pointing to the Person.propttype object. This object has a default attribute constructor(), Person.prototype.constructor--->Person. (In fact, the default here is to point to Object, and the correction will be made later)
What happens when we create an instance through a constructor?
function Person(){} Person.prototype={ first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatting");} }; var boy=new Person(); var girl=new Person();At this time, we need to know that the difference between a constructor and a function in js is the new keyword, and a function that uses the new operator is a constructor. When we create Person's instance object and save it in boy, girl, these two instance objects will generate a default attribute called _proto_ (which can be represented by [[prototype]] in ECMAScript5). This genus type points to the prototype object of the constructor, that is, boy._proto_--->Person.prototype (has nothing to do with the constructor). At this time, boy or girl can use points to call the genus type in the prototype object. At this time, you should know that boy and girl share the genus type of the prototype object. We can verify the above conclusion by isProtptypeOf() or object.getPrototypeOf() (the return value of this function is the prototype object, that is, the value of _proto_).
alert(Person.prototype.isPrototypeOf(boy)); //true alert(Object.getPrototypeOf(boy).first_name); //"guo"
At this time, we can do further verification. What if we create an attribute that is duplicated with the prototype object attribute in the instance?
var boy=new Person(); var girl=new Person(); boy.hair_color="red"; alert(boy.hair_color); //red alert(girl.hair_color); //black alert(Object.getPrototypeOf(boy).hair_color); //black
It can be seen that the duplicate attribute declared in the instance will block the properties in the prototype object, but it will only be overwritten and will not affect the genus type of the prototype object (Object.getPrototypeOf(boy).hair_color==black), nor will it affect the instance objects that share the genus type of the prototype object (girl.hair_color==black). At the same time, you can use the delete operator to delete the attributes declared by the instance object to undo the masking effect. We can use hasOwnProperty() to verify whether a genus exists in an instance (true) or in a prototype object (false).
alert(boy.hasOwnProperty("hair_color")); //trueYou can use Object.keys() to enumerate properties.
var key=Object.keys(Person.prototype); alert(key);
After learning these, we will find that using the above writing method to declare a prototype object, there will be a problem. The constructor no longer points to Person, which is contrary to the default pointing to a function containing the prototype attribute. This is because: every time a function is created, a prototype object will be automatically created, and this object will create a constructor by default. So, here our essence is to rewrite the default prototype, so the new constructuctor has also become a pointing to the Object function, no longer pointing to the Person function. If the constructor is really important, then you need to write constructor:Person.
After that, we need to know the dynamics of the prototype. Changing the properties in the prototype object will be reflected in the instance, regardless of whether the instance is created before or after the generic changes of the prototype object.
function Person(){} Person.prototype={ first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatation");} }; var boy=new Person(); Person.prototype.hobby="basketball"; var girl=new Person(); alert(boy.hobby); //basketballAs shown in the above code, even if the modification of the prototype object properties occurs after the instance creation, the boy instance still shares Person.prototype.hobby.
However, this situation only occurs when the prototype object attribute is modified. When the prototype object attribute is completely rewrite, the creation of the instance must be placed after the prototype object attribute rewrite, otherwise an error will occur.
function Person(){} var girl=new Person(); Person.prototype={ first_name:"guo", hair_color:"black", city:"zhengzhou", act:function(){alert("eatation");} }; var boy=new Person(); Person.prototype.hobby="basketball"; alert(boy.hobby); //basketball alert(girl.first_name); //undefinedGoing back to the issue of "blocking", we learned earlier that creating an instance object's attribute (same name as a certain attribute in the prototype object) will block the attribute of the prototype object, but will not affect other instance objects. There is an error here. This situation only applies to basic data types. When the value of the attribute refers to the type, a big problem will occur. See the following code.
function Person(){} Person.prototype={ first_name:"guo", hair_color:"black", friends:["Nick","John"], city:"zhengzhou", act:function(){alert("eatation");} }; var boy=new Person(); boy.friends.push("Mike"); var girl=new Person(); alert(boy.friends); //Nick, John,Mike alert(girl.friends); //Nick, John,MIkeIt can be seen that the above sentence does not apply, because friends exist in the prototype object, not in the boy, so its modification will affect this environment. (We can create a property of a boy instance through boy.frindes=[]) Then, we need to introduce a combination of constructor patterns and prototype patterns.
function Person(hair_color,city){ this.hair_color=hair_color; this.city=city; this.friends=["John","Nick"]; } Person.prototype={ constructor:Person, first_name:"guo", act:function() { alert("eatation"); } }; var boy=new Person("black","zhengzhou"); var girl=new Person("red","shenyang"); boy.friends.push("Nick"); alert(girl.friends); alert(boy.friends);This mode is the most widely used and most recognized method of creating custom types in ECMAScript, and can even be used as a default mode.
But for programmers working in other object-oriented languages, this pattern seems weird. In order to encapsulate all information into the constructor, the dynamic prototype pattern appears. The dynamic mode mainly uses an if statement to determine whether the prototype object needs to be initialized to achieve the purpose of saving resources.
In addition, there is a safe construction mode to adapt to the situation where there is no shared attribute and no use of this.
The above prototype analysis in JavaScript [Recommended] is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.