We know that JS is object-oriented. When it comes to object orientation, it is inevitable to involve the concept of classes. Generally, strongly typed languages like C# and Java have fixed syntax to define classes. The difference between JS is that it can use various methods to implement its own classes and objects. There are several general implementation methods:
1. Factory method
The factory method refers to creating a factory function that returns a specific object type. The example code is as follows:
The code copy is as follows:
function createCar(sColor,iDoors,iMpg)
{
var oTempCar=new Object;
oTempCar.color=sColor;
oTempCar.doors=iDoors;
oTempCar.mpg=iMpg;
oTempCar.showColor=function()
{
alert(this.color);
}
return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();
This way, every time it calls its factory function, a new object will be created. But the problem is that every time a new object is generated, a new function showColor must be created, which makes each object have its own version of showColor, and in fact, all objects share the same function. To solve this problem, the developer is The object's method is defined outside the factory function, and then the object is given a pointer to the function, as follows
The code copy is as follows:
function showColor()
{
alert(this.color);
}
function createCar(sColor,iDoors,iMpg)
{
var oTempCar=new Object;
oTempCar.color=sColor;
oTempCar.doors=iDoors;
oTempCar.mpg=iMpg;
oTempCar.showColor=showColor;
return oTempCar;
}
var oCar1=createCar("red",4,23);
var oCar2=createCar("blue",3,25);
oCar1.showColor();
oCar2.showColor();
This way, there is no need to create its own showColor function for each object, but just create a pointer to this function. This solves the problem functionally, but the function is not like the object's method. Therefore, the constructor method is introduced.
2. Constructor method
The constructor is very similar to the factory function, the example code is as follows:
The code copy is as follows:
function Car(sColor,iDoors,iMpg)
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.showColor=function()
{
alert(this.color);
}
}
var oCar1=new Car("red",4,23);
var oCar2=new Car("blue",3,25);
In the constructor, there is no object created internally, but the keyword this is used. When calling the constructor using the new operator, an object is created before executing the first line of code. Only this can be accessed. But what problems will happen with this? Obviously, each object of it will also create its own version of the showColor function. To solve this problem, the following prototype method was introduced.
3. Prototype method
This method takes advantage of the prototype property of the object, which can be regarded as the prototype on which a new object depends. Here, use the empty constructor to set the class name. Then all methods and attributes are directly assigned to the prototype attribute. as follows:
The code copy is as follows:
function Car()
{}
Car.prototype.color="red";
Car.prototype.doors=4;
Car.prototype.mpg=23;
Car.prototype.drivers=new Array("Mike","Sue");
Car.prototype.showColor=function()
{
alert(this.color);
}
The prototype method can only assign values directly, and cannot pass parameters to the constructor the value of the attribute initialization. When using this method, you will encounter two problems. I wonder if you have noticed it. The first problem is that each object must be created before the default value of the attribute can be changed in this way. It is not possible to directly have the property values you need when creating each object. This is annoying. The second problem is when the attribute refers to the object. There will be no problems with function sharing, but there will be problems with object sharing. Because each instance generally needs to implement its own object.
As follows:
The code copy is as follows:
var oCar1=new Car();
var oCar2=new Car();
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//Output "Mike,Sue,Matt"
alert(oCar2.drivers);//Output "Mike,Sue,Matt"
Therefore the drivers attribute is just a pointer to the object, so all instances actually share the same object. Due to these problems, we introduce the following joint use constructor and prototype method.
4. Mixed constructor/prototype method
The idea of this method is to use a constructor to define all non-functional properties of an object (including ordinary properties and attributes pointing to the object), and use a prototype to define the function properties (methods) of an object. The result is that all functions are created only once, and each object has its own object attribute instance. The sample code is as follows:
The code copy is as follows:
function Car(sColor,iDoors,iMpg)
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.drivers=new Array("Mike","Sue");
}
Car.prototype.showColor=function()
{
alert(this.color);
}
var oCar1=new Car("red",4,23);
var oCar2=new Car("blue",3,25);
oCar1.drivers.push("Matt");
alert(oCar1.drivers);//Output "Mike,Sue,Matt"
alert(oCar2.drivers);//Output "Mike,Sue"
As can be seen from the example code, this method solves two problems in the previous method at the same time. However, in this way, some developers still feel that it is not perfect.
5. Dynamic prototype method
We can see that most object-oriented languages visually encapsulate properties and methods. However, the showColor method in the above method is defined outside the class. Therefore, they designed a dynamic prototype approach. The basic idea of this approach is the same as the mixed constructor/prototype approach, the only difference is the location of the object method. As shown below:
The code copy is as follows:
function Car(sColor,iDoors,iMpg)
{
this.color=sColor;
this.doors=iDoors;
this.mpg=iMpg;
this.drivers=new Array("Mike","Sue");
if(typeof Car._initialized=="undefined")
{
Car.prototype.showColor=function()
{
alert(this.color);
}
}
Car._initialized=true;
}
This way Car.prototype.showColor is created only once. This dependency makes this code more like the class definition in other languages.
6. Mixed factory method
This approach is usually a workaround that cannot be used as the former approach. Its purpose is to create a fake constructor that returns only new instances of another object.
The code copy is as follows:
function createCar()
{
var oTempCar=new Object;
oTempCar.color="red";
oTempCar.doors=4;
oTempCar.mpg=23;
oTempCar.showColor=function()
{
alert(this.color);
};
return oTempCar;
}
var car=new Car();
Since the new operator is called inside the Car() constructor, the second new operator is automatically ignored. Objects created inside the constructor are passed back to the variable var. This approach has the same problems as the classic approach in terms of internal management of object methods. Therefore, it is highly recommended: avoid using this method unless it is absolutely necessary.