Transferred from:Http://developer.51cto.com/art/201105/261407.htm
This article is written in chapter 7, 8 and 9 of <JavaScript-the definitive guide, 5th edition>, I will try to describe the Javascript object-oriented technology (Object/array-> function --> class/constructor/prototype) according to the structure of the original book ). I will attach the original English statement for your reference.
Class, constructor, prototype
Note: As mentioned above, each function contains a prototype attribute, which points to a prototype object. Do not confuse it.
Constructor:
The new operator is used to generate a new object. New must be followed by a function, that is, the constructor we often call. What is the working principle of the constructor?
Let's take a look at an example:
JS Code
- function Person(name,sex) {
- this.name = name;
- this.sex = sex;
- }
- var per = new Person("sdcyst","male");
- alert("name:"+per.name+"_sex:"+per.sex); //name:sdcyst_sex:male
The following describes the procedure:
A function (not a method, but a common function) is created. Note that this keyword is used. previously we mentioned this keyword to indicate the object that calls this method, that is, when you call a "method" through an object, this keyword will point to this object (this points to the entire script domain, or the domain of the function if the function is called directly without an object, which we will not discuss in detail here ).
When we use the new operator, JavaScript will first create an empty object, and then this object is referenced by the this keyword of the method (function) next to New! Then, through this operation in the method, the newly created object is Assigned attributes. finally, the processed object is returned. in this case, the above example is clear: first create an empty object, then call the person method to assign values to it, and finally return the object, we get a per object.
Prototype-the prototype object and prototype attribute are repeatedly mentioned here.
In JavaScript, each object has a prototype attribute that points to a prototype object. we mentioned the process of creating an object with new. In fact, when an empty object is created, new will operate on the prototype attribute of the newly generated object.
Each method has a prototype attribute (because the method itself is also an object). The prototype attribute value of the new object generated by the new operator is consistent with that of the constructor. the prototype attribute of the constructor method points to a prototype object. This prototype object has only one constructor initially, and this constructor attribute points to the method where the prototype attribute is located, see the following figure:
In this way, when a constructor is used to create a new object, it will obtain all the attributes of the prototype object pointed to by the prototype attribute of the constructor. any operation on the prototype object corresponding to the constructor will be reflected to the object generated by the constructor. All these objects share the properties (including methods) of the prototype object corresponding to the constructor ).
Let's take a look at the specific example:
JS Code
- FunctionPerson (name, sex) {// Constructor
- This. Name = Name;
- This. Sex = sex;
- }
- Person. Prototype. Age = 12; // assign a value to the attribute of the prototype object corresponding to the prototype attribute
- Person. Prototype. Print =Function() {// Add Method
- Alert (This. Name + "_" +This. Sex + "_" +This. Age );
- };
- VaRP1 =NewPerson ("name1", "male ");
- VaRP2 =NewPerson ("name2", "male ");
- P1.print (); // name1_male_12
- P2.print (); // name2_male_12
- Person. Prototype. Age = 18; // change the attribute value of the prototype object. Note that the prototype attribute of the constructor is used.
- P1.print (); // name1_male_18
- P2.print (); // name2_male_18
So far, we have simulated the implementation of simple classes. We have constructors, class attributes, and class methods to create "instances ". in the following article, we use the name "class" to replace the constructor method. However, this is just a simulation, not a real Object-Oriented "class ".
Before proceeding to the next step, let's take a look at how to change the prototype attribute of an object and how to set the prototype attribute. Note: it may help us to understand the problem: after we create an object, this object will obtain the prototype attribute (including functions and variables) of the constructor, which can be considered as a constructor (class) inherits the functions and variables of the prototype object corresponding to its prototype attribute. That is to say, the prototype object simulates the effect of a super class. let's look at an instance:
JS Code
- FunctionThe constructor of the person (name, sex) {// person class
- This. Name = Name;
- This. Sex = sex;
- }
- Person. Prototype. Age = 12; // assign a value to the attribute of the prototype object corresponding to the prototype attribute of the person class,
- // Equivalent to adding an attribute to the parent class of the person class
- Person. Prototype. Print =Function() {// Add method for the parent class of the person class
- Alert (This. Name + "_" +This. Sex + "_" +This. Age );
- };
- VaRP1 =NewPerson ("name1", "male"); // The age attribute of P1 inherits the parent class (prototype object) of the Child person class)
- VaRP2 =NewPerson ("name2", "male ");
- P1.print (); // name1_male_12
- P2.print (); // name2_male_12
- P1.age = 34; // change the age attribute of the P1 instance
- P1.print (); // name1_male_34
- P2.print (); // name2_male_12
- Person. Prototype. Age = 22; // change the age attribute of the person class's superclass.
- P1.print (); // name1_male_34 (the age attribute of P1 has not changed with the prototype attribute)
- P2.print (); // name2_male_22 (the age attribute of P2 has changed)
- P1.print =Function() {// Change the print method of the P1 object
- Alert ("I am p1 ");
- }
- P1.print (); // I am p1 (the P1 method has changed)
- P2.print (); // name2_male_22 (the P2 method has not changed)
- Person. Prototype. Print =Function() {// Change the print method of the person superclass
- Alert ("new print method! ");
- }
- P1.print (); // I am p1 (the print method of P1 is still its own method)
- P2.print (); // new print method! (The print method of P2 changes with the change of the superclass method)
I have read an article that describes that the prototype attribute of an object in Javascript is equivalent to the static variable in Java and can be shared by all objects in this class. The above example shows that the actual situation is not like this:
In JS, when we create an instance object of a class using the new operator, its methods and attributes actually inherit the prototype attribute of the class, the methods and attributes defined in the prototype attribute of the class can be directly referenced by these instance objects. however, when we re-assign or define the attributes and methods of these instance objects, the attributes or methods of the Instance objects will no longer point to the attributes and methods defined in the prototype attribute of the class, at this time, even if you modify the corresponding method or attribute in the prototype attribute of the class, it does not reflect on the instance object. this explains the example above:
In the beginning, two objects P1 and P2 are generated using the new operator. Their age attributes and print methods both come from the prototype attribute of the person class. then, we modified the age attribute of P1, and then assigned a value (person. prototype. age = 22), the age attribute of P1 does not change, but the age attribute of P2 changes accordingly, because the age attribute of P2 is still derived from the prototype attribute of the person class. the same situation is also reflected in the print method later.
Through the above introduction, we know that the prototype attribute simulates the role of the parent class (superclass) in Javascript, and reflects the object-oriented idea in JS. The prototype attribute
Is critical.