Let’s first illustrate with an example:
function myClass() { var id = 1; var name = "johnson"; //properties this.ID = id; this.Name = name; //method this.showMessage = function() { alert("ID: " + this.ID + ", Name: " + this.Name); } } var obj1 = new myClass(); var obj2 = new myClass();
The definition of function is actually equivalent to the constructor of the class, and the last two sentences are to create an instance of this class. Let’s analyze the first sentence first: var obj1 = new myClass(); When using new to create an instance of a class, the interpreter will first create an empty object. Then run this myClass function and point this pointer to an instance of this class. When encountering this.ID = id; and this.Name = name; and this.showMessage = function(){...}, these two properties and this method will be created, and the variables id and name will be The definition of the value-level function is assigned to these two properties and this function object (shwoMessage). This process is equivalent to initializing the object, similar to the constructor in C#. Finally new returns this object. Look at the second sentence: var obj2 = new myClass(); The execution process is the same as the previous sentence, that is, creating an empty object, then executing the myClass function and defining two properties and a method.
As can be seen from the above analysis, the above way of implementing a class is to define the attribute method of the class in the definition of the function. There are disadvantages. If two or more instances of this class need to be created, as shown above, these properties will be created multiple times.
So how to avoid this situation? Prototype is a prototype like its name. Each function has a sub-object prototype, which actually represents the collection of members of this function object. Since here we use functions to implement classes, we can say that prototype is actually the class. A collection of members. The properties and methods defined by the prototype are executed before the function's constructor is executed, so before an object is new, the members of the prototype have actually been executed. Let’s look at an example first: The structure of the
function myClass() { //构造函数 } myClass.prototype = { ID: 1, Name: "johnson", showMessage: function() { alert("ID: " + this.ID + ", Name: " + this.Name); } } var obj1 = new myClass(); var obj2 = new myClass();
class is still the same as the previous example, but here it is implemented using prototype. Let’s look at the last two sentences first. As mentioned before, prototype is executed before the function constructor, that is, before var obj1 = new myClass(); is executed, this class already has an ID, Name attribute and showMessage method. The execution process of the executor is as follows. Note the comparison with the previous example: first, create an empty object and point the this pointer to this object. Then assign all members of the function's prototype object to this object (note that these members are not created again). Then execute the function body. Finally new returns this object. When executing the next sentence: This process is also executed and these members will not be created repeatedly.
The above code is just an example. In actual projects, there may be a large number of members in the class, and a large number of instances may need to be created. This prototype will show its superiority. In addition, the above code uses brace syntax to define members of the prototype, so that the code looks clearer. This is a recommended class design pattern. Of course, in many projects, we may find better models. We also hope to have more optimized JavaScript programming models to continue to introduce new ones. We also hope that as time goes by, all mainstream browsers will also standardize JavaScript parsing. ,Unite.
As mentioned above, the members defined by prototype occur before the constructor. It can be proved that in the above example, the constructor is empty. Add an alert(this.Name); to the constructor. When the execution reaches When var obj1 = new myClass();, you will see a pop-up dialog box showing the correct attribute values.
The following code:
function subClass(){ } subClass.prototype = { Name: "sub" } function myClass() { //构造函数 } myClass.prototype = { ID: 1, Name: "johnson", SubObj: new subClass(), showMessage: function() { alert("ID: " + this.ID + ", Name: " + this.Name + "SubObj.Name:" + this.SubObj.Name); } } var obj1 = new myClass(); obj1.SubObj.Name = "XXX"; obj1.showMessage(); var obj2 = new myClass(); obj2.showMessage();
Here a reference type is defined in myClass, its type is a subClass class we customized, and there is a Name attribute in this subclass. Since the prototype object is shared, according to our analysis above: when executing var obj1 = new myClass();, the members of the prototype of myClass will be copied to this obj1 instance. But SubObj here is a reference type. When var obj2 = new myClass(); is executed, the ID and Name members in the prototype will be copied to obj2, but the SubObj attribute will not be copied, but will refer to the prototype. SubObj, so because the previous sentence modified the value of obj1.Subobj.Name, when using new to generate an obj2 instance, the modified value is referenced.
So when you use prototype to define a class, you still need to define the attributes in the constructor and define the methods on the prototype of the constructor. As follows:
function myClass(id, name) { this.ID = id; this.Name = name; } myClass.prototype = { showMessage: function() { alert("ID: " + this.ID + ", Name: " + this.Name); }, showMessage2: function() { alert("Method2"); } } var obj1 = new myClass(1, "johnson"); obj1.showMessage(); obj1.Name="John"; obj1.showMessage(); var obj2 = new myClass(2, "Amanda"); obj2.showMessage();
The above is the detailed content of Detailed explanation of usage of defining class instances in JavaScript through functions. For more information, please follow other related articles on the PHP Chinese website!