Classes
Classes are objects that share the same properties.
A member of a class is called the instance of that class. For example, in the example below, object is an instance of the Object class.
const object = new Object();
Defining a class
JavaScript classes are implemented using prototype-based inheritance. If two objects are members from the same class, they would inherit from the same prototype.
Using a factory function
Not the idiomatic way to define a class.
Using a constructor function
A constructor is a function designed to be invoked with new.
This was the way to declare classes before ES6 introduced the class syntax.
Using the class syntax
The class syntax is introduced in ES6 as a "syntactic sugar" for defining classes. Unlike function declarations, they are "hoisted" to the top of the scope.
At the end of the day, your class definition will still be evaluated as a constructor function just like the above.
The prototype and the constructor property
prototype
Although almost all objects have a prototype, only functions (excluding arrow functions, generator functions, and async functions) have the prototype property.
(For example, it makes sense to query <functionName>.prototype.)
The property will<functionName>.prototype be used as the object's prototype when you call new <functionName>().
constructor
The prototype property is an object that contains a single, non-enumerable constructor property that links back to the constructor function.
Since constructor is a property of an object's prototype, then naturally, all object will also inherit the constructor property.
Modifying prototypes
JavaScript's prototype-based inheritance is dynamic: if you add a new method to it, then the classes inheriting from it will also inherit the new method.
Note, however, that this is considered a bad idea because "it will cause confusion and compatibility problems" with future versions of JavaScript (Flanagan).
Extending a class
If class B extends class A:
- It means that class B will inherit properties of class A. (B can override some or all of the inherited properties, though.)
- We can say that class B is the subclass of class A.
- We can say that class A is the superclass of class B.
Extending using constructor functions
In the example below,
- objects created with
new Subclass()will inherit fromSubclass.prototype, - but
Subclass.prototypeis an object that inherits fromSuperclass.prototype(recallObject.create) - so, objects created with
new Subclass()will inherit from bothSubclass.prototypeandSuperclass.prototype
function Superclass() {...}
Superclass.prototype = {...};
// `Subclass` inherits from `Superclass`
function Subclass() {...}
Subclass.prototype = Object.create(Superclass.prototype);
// If we want to override the constructor
Subclass.prototype.constructor = Subclass;
// If we want to override a method
Subclass.prototype.methodName = function () {...};
Extending using the class syntax
Use the extends keyword.
Inside the subclass constructor, you can use super() to call the superclass' constructor.
class Subclass extends Superclass {
constructor(...args) {
// ... do something ...
super(...args);
// ... do something ...
}
// If you want to implement or or override
// a method, just write it here.
methodName() {
// ... do something ...
}
}
Static functions
Using the class syntax, you can declare static functions: functions that are called on the class itself, rather than the class instances.
Just put static before the function name inside the class definition.
Instance and static fields
At the time of writing, there is no finalized specification for defining fields, although "standardization is underway" (Flanagan).
The current way:
- To write instance fields — do so in the constructor, using
this.<fieldName> - To write static fields — assign it to the class outside the
classbody, after the class have been defined
class MyClass {
constructor() {
// Write instance fields inside the constructor
this.instanceField1 = 'someValue';
this.instanceField2 = 'someValue';
}
}
// Write static fields outside the class
MyClass.staticField1 = 'anotherValue';
MyClass.staticField2 = 'anotherValue';
References
- JavaScript: The Definitive Guide, 7th Edition (David Flanagan) — Chapter 9. Classes