In JavaScript, class can be used to implement object-oriented programming. However, classes in JavaScript are different from those in Java, and their corresponding definitions and uses are also different.
Definition of classes in JavaScript
In JavaScript, all objects derived from the same prototype object (prototype) form a class; that is, classes in JavaScript are concepts of an object collection. If two objects have the same prototype, they belong to the same class; classes in JavaScript do not even need class names. The following code is an example:
The code copy is as follows:
var p = {x:42};
var a = Object.create(p);
var b = Object.create(p);
console.log(a === b);//false
console.log(Object.getPrototypeOf(a) === Object.getPrototypeOf(b));//true
In the above example, objects a and b have the same prototype object (prototype) p, so a and b belong to the same class (although neither of this class has a class name), and they inherit the property x with a value of 42 from the prototype object p.
From this example, we can see that the function of a prototype object is equivalent to a template, and multiple objects can be derived/created from it. Its status is the same as that of the class code in the Java language and is the core of class definition in JavaScript. The prototype object in the following example will appear more like class code:
The code copy is as follows:
var p = {
INCREMENT_BY : 1,
increment: function(x){
return x + this.INCREMENT_BY;
}
}
var a = Object.create(p);
var b = Object.create(p);
console.log(a.increment(7));//8
console.log(b.increment(9));//10
In the above example, the prototype object p defines a property (INCREMENT_BY) with a value of 1 and a function named increment; objects a and b obtain the INCREMENT_BY and increment functions from the template p. When calling the increment function of object a or b, JavaScript will try to get the INCREMENT_BY value of a or b (this.INCREMENT_BY); since INCREMENT_BY is obtained from p, its values are all 1 - variables with the same values, similar to static class variables in Java. Therefore, in the example above, all capital characters are used when naming the INCREMENT_BY variable.
In the above example, all objects created from template p (the objects belonging to the same class) have the same properties and behavior. But in fact, for different objects of the same class, in addition to having attributes/behaviors defined by the class, they often have some unique attributes and behaviors. Therefore, if you need to use the prototype template as a class, you must customize each object derived from it:
The code copy is as follows:
var p = {
INCREMENT_BY : 1,
increment: function(x){
return x + this.INCREMENT_BY + this.custom_increment_by;
}
}
var a = Object.create(p);
var b = Object.create(p);
a.custom_increment_by = 0;
b.custom_increment_by = 1;
console.log(a.increment(7));//8
console.log(b.increment(9));//11
In this example, objects a and b created from template p have a variable custom_increment_by whose values are not necessarily equal to each other, and the final result of their increment() function behavior is related to the value of custom_increment_by. Generally speaking, the work of customizing new objects is often carried out in a unified function:
The code copy is as follows:
var p = {
INCREMENT_BY : 1,
increment: function(x){
return x + this.INCREMENT_BY + this.custom_increment_by;
}
}
function getIncrementalClassObject(customIncrementByValue){
var incrementalObj = Object.create(p);
incrementalObj.custom_increment_by = customIncrementByValue;
return incrementalObj;
}
var a = getIncrementalClassObject(0);
var b = getIncrementalClassObject(1);
console.log(a.increment(7));//8
console.log(b.increment(9));//11
In this way, a class definition is completed through the prototype object p and getIncrementalClassObject() functions: the prototype objects whose prototype objects are p can be obtained by calling the getIncrementalClassObject() function, and these new objects can be customized to a certain extent during the call to the getIncrementalClassObject() function. It is worth noting that this defined class does not have a class name at this time. For the sake of description, it will be called Incremental.
Looking back at the work done in the getIncrementalClassObject() function, you can see that the process of creating a new object from the Incremental class is as follows:
1. Create an empty object and define its prototype object as p.
2. Customize this newly created empty object according to different parameter values.
3. Return a new object that has been customized.
In JavaScript, you can quickly complete the definition of the class and the creation of new objects by using the Constructor.
Constructor (constructor) in JavaScript
From the example of the Incremental class above, we can see that defining a new class requires two parts of code: creating a prototype object as a template, creating a custom function to initialize the new object; creating a new object from a class goes through three processes: specifying the prototype object of the new object, customizing/initializing the new object, and returning this new object. In JavaScript, all this can be done through the Constructor (constructor).
The Constructor in JavaScript is a function that assumes the responsibility of initializing a new object; the prototype of this Constructor function is used as a template to create a new object. Taking the above Incremental class as an example, after using Constructor to rewrite the code, it looks like this:
The code copy is as follows:
function Incremental(customIncrementByValue){
this.custom_increment_by = customIncrementByValue;
}
Incremental.prototype = {
INCREMENT_BY : 1,
increment: function(x){
return x + this.INCREMENT_BY + this.custom_increment_by;
}
}
var a = new Incremental(0);
var b = new Incremental(1);
console.log(a.increment(7));//8
console.log(b.increment(9));//11
The process of creating a new object using the Constructor function through the new keyword actually goes through the following stages:
Create a new empty object.
1. Point the prototype object of this object to the prototype property of the constructor function.
2. Use this object as this parameter and execute the constructor function.
3. This is the same thing as the previous work done in the getIncrementalClassObject() function.
Class Name
When creating an object using Constructor, the corresponding object has a "class name", which can be verified from the result of the instanceof operator:
The code copy is as follows:
console.log(a instanceof Incremental);//true
console.log(b instanceof Incremental);//true
However, the instanceof operator does not determine whether the object is created by the Incremental constructor. The instanceof operator only determines whether the object's prototype object is Incremental.prototype. When there are two constructors with the same prototype, the instanceof operator will return true uniformly without distinguishing which constructor is used to create the object.
The code copy is as follows:
function Incremental2(customIncrementByValue){
this.custom_increment_by = customIncrementByValue + 3;
}
Incremental2.prototype = Incremental.prototype;
console.log(a instanceof Incremental2);//true