In modern programming languages, classes are one of the core concepts in the object-oriented programming paradigm.
Similar to functions, classes are essentially special functions that allow us to encapsulate data and operations together to create objects with common behavior and state.
In the world of classes, we have class expressions and class declarations, each of which has its own characteristics and uses.
kind
✨A class is essentially a special kind of function. So just like functions, there are class expressions and class declarations
class declaration
Unlikefunctions, class declarations are not hoisted. This means that a class declaration needs to be made before using it. Class declarations usually include constructors and other member methods. A constructor is a special method used to create and initialize objects created by a class.
// 类声明
class Rectangle {
constructor(height, width) {
this.height = height; // 实例成员
this.width = width;
}
}
let p = new Rectangle();
class expression
- Class expressions can be named or unnamed
- We can retrieve it through the name attribute of the class
// 未命名/匿名类
let Rectangle = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
// output: "Rectangle"
// 命名类
// 命名类表达式的名称是该类体的局部名称。
let Rectangle = class Rectangle2 {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
console.log(Rectangle.name);
// 输出:"Rectangle2"
Class definition
{}
The part inside is called the class body.- The class body will include:
-
Constructor
- The constructor method is a special method that is used to create and initialize an object created by
class
. - Note⚠️: There can only be one constructor method in a class body
- Use
super
keyword to call a parent class constructor
- The constructor method is a special method that is used to create and initialize an object created by
-
prototype method
class Rectangle { // constructor constructor(height, width) { // 实例的属性必须定义在类的方法里 this.height = height; this.width = width; } // Getter get area() { return this.calcArea(); } // Method calcArea() { return this.height * this.width; } } const square = new Rectangle(10, 10); console.log(square.area); // 100
-
static method
- static to define a static method, can only be accessed by the class
class Point { constructor(x, y) { this.x = x; this.y = y; } static displayName = "Point"; static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.hypot(dx, dy); } } const p1 = new Point(5, 5); const p2 = new Point(10, 10); p1.displayName; // undefined p1.distance; // undefined console.log(Point.displayName); // "Point" console.log(Point.distance(p1, p2)); // 7.0710678118654755
-
getters and setters
-
- Follow the strict mode in the class body
this-oriented
in class
-
Member methods in a class body follow a strict pattern. This behaves differently in class methods than in traditional functions. When calling a static or prototype method, this points to undefined by default, but in non-strict mode, it is automatically boxed to retain the incoming state.
-
when called. Who calls, who points to
class Animal { // 原型方法 speak() { return this; } // 静态方法 static eat() { return this; } } let obj = new Animal(); obj.speak(); // Animal {} let speak = obj.speak; speak(); // undefined Animal.eat(); // class Animal let eat = Animal.eat; eat(); // undefined
in traditional functions
When a function is called in non-strict mode, autoboxing occurs. That is, if the initial value is undefined, this points to the global object.
function Animal() {
}
Animal.prototype.speak = function () {
return this;
};
Animal.eat = function () {
return this;
};
let obj = new Animal();
let speak = obj.speak;
speak(); // global object
let eat = Animal.eat;
eat(); // global object
Field declaration
public fields
- No need for let, const and other keywords
- Announcement in advance
class Rectangle {
height = 0;
width;
constructor(height, width) {
this.height = height;
this.width = width;
}
}
private field
- It can only be read inside the class and cannot be called from outside.
- Private fields can only be predefined in the field declaration.
class Rectangle {
#height = 0;
#width;
constructor(height, width) {
this.#height = height;
this.#width = width;
}
}
extends
We can create a subclass to extend the functionality of the parent class. Subclasses inherit the properties and methods of the parent class and can be extended or rewritten based on them.
class Father {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${
this.name} makes a noise.`);
}
}
class Son extends Father {
constructor(name) {
super(name); // 调用超类构造函数并传入 name 参数
}
speak() {
console.log(`${
this.name} barks.`);
}
}
var d = new Son("Mitzie");
d.speak(); // 'Mitzie barks.'
super
super
The keyword is used to call functions on the parent object of the object.
class Father {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + " makes a noise.");
}
}
class Son extends Father {
speak() {
super.speak();
console.log(this.name + " roars.");
}
}
| Text reference:MDN