When we talk about object -oriented, we can think of class, objects, packaging, inheritance, polymorphism. In the book "JavaScript Advanced Program Design" (People's Post and Telecommunications Press, Cao Li, Zhang Xin. The English name is: Professional JavaScript for Web Developers) is described in the book. Let's take a look at the various methods defined in JavaScript.
1. Factory method
Create our own class and objects in JavaScript, we should have to master. We all know that the attributes of the object in JavaScript can be dynamically defined after the object creation, such as the following code:
Copy code code as follows:
<script type = "text/javascript">
//definition
var ocar = new object ();
ocar.color = "red";
ocar.doors = 4;
ocar.showcolor = function () {
Alert (this.color);
}
// Call
ocar.showcolor ();
</script>
We are easy to use OCAR objects, but we create multiple CAR instances. We can use a function to encapsulate the code above to implement:
Copy code code as follows:
<script type = "text/javascript">
//definition
function createcar () {
var ocar = new object ();
ocar.color = "red";
ocar.doors = 4;
ocar.showcolor = function () {
Alert (this.color);
}
Return OCAR;
}
// Call
var ocar1 = createcar ();
var ocar2 = createcar ();
ocar1.color = "Black";
ocar1.showcolor ();
ocar2.showcolor ();
</script>
By the way, the default membership attributes of the JavaScript object are Public. In this way, we call it a factory method, and we have created factories that can create and return specific types of objects.
This is a bit interesting, but in the object -oriented object, the method of creating the object is:
Car car = new car ();
The use of New keywords has been deeply rooted in the hearts of the people, so we use the above method to define it. It always feels awkward, and every time we call it, we create new attributes and functions. The function is not practical. Let's look at the form definition of the constructor.
2. Constructor
This method looks a bit like a factory function. The specific performance is as follows:
Copy code code as follows:
<script type = "text/javascript">
//definition
Function Car (COLOR, Doors) {
this.color = color;
this.Doors = Doors;
this.showcolor = function () {
Alert (this.color);
};
}
// Call
var car1 = new car ("red", 4);
var car2 = new car ("blue", 4);
car1.showcolor ();
car2.showcolor ();
</script>
It looks obvious, there are differences. It feels a bit interesting. Create an object inside the constructing function using this keywords, and it feels very kind to create objects using the new computing symbol. But there are also some problems: every time the NEW object is created, all attributes, including the creation of the function, that is to say that multiple objects are completely independent. The purpose of our definition is to share methods and data, but the CAR1 object and CAR2 object are both. At least we should share the methods and functions of their independent attributes. This is the advantage of the original form.
3. Prototype
Using the object's prototype attribute, you can see the prototype that the new object depends on. The method is as follows:
Copy code code as follows:
<script type = "text/javascript">
//definition
fuinction car () {
};
Car.prototype.color = "red";
Car.prototype.doors = 4;
Car.prototype.drivers = New Array ("Tom", "Jerry");
Car.prototype.showcolor = Function () {
Alert (this.color);
}
// Call:
var car1 = new car ();
var car2 = new car ();
car1.showcolor ();
car2.showcolor ();
alert (car1.drivers);
car1.drivers.push ("Stephen");
alert (car1.drivers); // Results: tom, jerry, stephen
alert (car2.drivers); // Results: tom, jerry, stephen
// You can use JSON to simplify the definition of prototype:
Car.prototype =
{{
color: "red",
Doors: 4,
Drivers: ["tom", "jerry", 'safdad'],
showcolor: function () {
Alert (this.color);
}
}
</script>
First of all, the constructor of this code, there is no code, and then add the attribute of the object to define the attribute of the car object through the prototype attribute of the object. This method is very good, but the problem is that the object of CAR points to the Array pointer. The two objects of CAR point to the same ARRAY array. One of the objects CAR1 change the reference (array Array), and the other object CAR2 also At the same time, this is not allowed.
At the same time, the problem is also manifested in the prototype that cannot bring any initialization parameters, which makes the constructor cannot initialize normally. This requires another way to solve: that is the mixed constructor/prototype mode.
4. Mixed constructor/prototype mode
The combination of constructor and prototype is very convenient to define the class.
Copy code code as follows:
<script type = "text/javascript">
//definition
Function Car (COLOR, Doors)
{{
this.color = color;
this.Doors = Doors;
this.drivers = New Array ("Tom", "Jerry");
}
Car.prototype.showcolor = Function () {
Alert (this.color);
}
// Call:
var car1 = new car ('red', 4);
var car2 = new car ('blue', 4);
car1.showcolor ();
car2.showcolor ();
alert (car1.drivers);
car1.drivers.push ("Stephen");
alert (car1.drivers); // Results: tom, jerry, stephen
alert (car2.drivers); // Results: tom, jerry
Alert (Car1 Instanceof Car);
</script>
This method is to define the attributes inside, and use the prototype to define it outside. The problem of solving the third method.
This method should actually be very friendly, but compared to Java's grammar, there should be some disharmony, and it feels more messy. For C ++, we don't feel so troublesome. However In the case, it rarely involves JavaScript, and for J2EE R & D personnel, this method is always awkward. It always feels that it is not a friendly packaging. In fact, it is just that the visual packaging effect is not very good. If you want to achieve the effect of the visual packaging and achieve this method, you can also use it. Personally, it is considered that it is more troublesome. That is the dynamic prototype.
5. Dynamic prototype
For developers who are accustomed to using other languages, the use of mixed constructor/prototypes is not so harmonious. After all, when defining categories, most object -oriented languages are visually packaged on attributes and methods. Consider the following C#class:
Copy code code as follows:
class car // class
{{
public string color = "red";
Public int doors = 4;
public int mpg = 23;
public car (String color, int doors, int mpg) // constructor
{{
this.color = color;
this.Doors = Doors;
this.mpg = mpg;
}
public void showcolor () // medhod
{{
Console.writeline (this.color);
}
}
C#is well packed all the attributes and methods of the CAR class, so when you see this code, you know what functions it is to achieve, and it defines an object's information. People who criticize the constructor/prototype of mixed constructors believe that the method of finding attributes in the constructor's memory, and the method of finding methods outside of it is not logical. Therefore, they designed a dynamic prototype to provide more friendly coding style.
The basic idea of dynamic prototype method is the same as the constructor/prototype of the mixed structure, that is, define non -function attributes in the constructor, and the function attribute is defined using the prototype attribute. The only difference is the position of the object method. The following is the car class rewritten by dynamic prototype:
Copy code code as follows:
<script type = "text/javascript">
//definition
fuinction car () {
this.color = "red";
this.doors = 4;
this.drivers = New Array ("Tom", "Jerry");
ifof car._initialized == "undefined") {{
Car.prototype.showcolor = Function () {
Alert (this.color);
}
// ............
}
// Last definition
Car._initialized = true;
}
</script>
Until checking the typeof car._initialized equivalent equal to "undefined", this constructor has not changed. This line of code is the most important part of the dynamic prototype method. If this value is not defined, the constructor will continue to define the object method by prototype, and then set the car._initialized to true. If this value is defined (when its value is true, the value of Typeof is BOOLEAN), then this method will not be created. In short, this method uses the logo (_initialized) to determine whether it has given any method to the prototype. This method is only created and assigned once. To please the traditional OOP developers, this code looks more like a class definition in other languages.
6 Hybrid factory method
This method is usually a way to change the way when the previous method cannot be applied. Its purpose is to create a fake constructor and return only a new example of another object. This code seems to be very similar to the factory function:
Copy code code as follows:
fuinction car () {
var ompcar = new object ();
ionmpcar.color = "red";
ionmpcar.doors = 4;
ionmpcar.mpg = 23;
ionMPCAR.SHOWCOLOR = Function () {
Alert (this.color);
}
Return OTEMPCAR;
}
Different from the classic method, this method uses the new operator to make it look like a real structure function:
var ocar = new car ();
Because the new operator is called inside the CAR () constructor, the second new operator will be ignored (located outside the constructor). The object created in the constructor is passed back to the variable VAR. This method has the same problems as the classic methods of the object method. Strongly recommended: Unless you have to (see Chapter 15), you still avoid this method.
Summary: (which method is used)
At present, the most widely used is a mixed constructor/prototype. In addition, dynamic prototypes are also very popular, and are equivalent to the functional function/prototype in function. You can use any of these two methods. However, do not use the classic constructor or prototype, because this will introduce the code to the problem.
Copy code code as follows:
// ps
// Static class (1: Function)
varcollection = new function () {
var _Carcollection = New Array (); // Global, Private
this.add = function (objcar) {
alert ('add');
}
this.get = Function (Carid) {
alert ('get');
}
}
// static class (2: json)
var car = {
color: 'Red',
Doors: 4,
showcolor: function () {alert (this.color);}
}
Car.showcolor ();