类主体
类的主体是其被花括号 {} 包裹的部分。这里是你定义方法或构造函数等类成员的地方。
类的主体会执行在严格模式下,即便没有写 "use strict" 指令也一样。
可以从以下三个方面表述一个类元素的特征:
种类:getter、setter、方法、字段
位置:静态的或位于实例上
可见性:公有或私有
它们总共有 16 种可能的组合。为了更合理地划分参考文献,避免内容重叠,不同的元素会在不同的页面进行详细的介绍:
方法的定义
公有的实例方法
getter
公有的实例 getter 方法
setter
公有的实例 setter 方法
类公有字段
公有的实例字段
static
公有的静态方法、静态 getter、静态 setter 和静态字段
私有元素
所有私有的元素
备注:私有元素具有在同一个类种声明的所有元素的名称必须唯一的限制。其他所有的公有属性都没有这个限制——你可以写多个同名的公有属性,但是最后一个会覆盖掉其他的。此种表现与对象初始化器相同。
另外,有两种特殊的类元素语法:constructor 和静态初始化块,它们有自己的参考资料。
构造函数
constructor 方法是用于创建和初始化一个由类创建的对象的特殊方法。一个类只能拥有一个名为“constructor”的特殊方法。如果类包含多个 constructor 方法,将会抛出一个 SyntaxError。
构造函数可以使用 super 关键字来调用父类的构造函数。
你可以在构造方法中创建实例的属性:
jsclass Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
或者,如果实例属性的值不依赖构造函数的参数,那么你可以把它们定义为类字段。
静态初始化块
静态初始化块使静态属性可以灵活初始化,包括在初始化期间执行语句、授予外部对私有作用域的访问权等。
可以声明多个静态块,并且它们可以与静态字段和方法随意穿插(所有的静态项会按照声明顺序被执行或求值)。
方法
方法被定义在类实例的原型上并且被所有实例共享。方法可以是普通函数、异步函数、生成器函数或异步生成器函数。更多信息,参见方法的定义。
jsclass Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// getter 方法
get area() {
return this.calcArea();
}
// 方法
calcArea() {
return this.height * this.width;
}
*getSides() {
yield this.height;
yield this.width;
yield this.height;
yield this.width;
}
}
const square = new Rectangle(10, 10);
console.log(square.area); // 100
console.log([...square.getSides()]); // [10, 10, 10, 10]
静态方法和字段
static 关键字用来定义类的静态方法或字段。静态属性(字段和方法)被定义在类的自身而不是类的实例上。静态方法通常用于为应用程序创建工具函数,而静态字段则多用于存放缓存、固定配置或其他不需要跨实例复制的数据。
jsclass 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
p2.displayName; // undefined
p2.distance; // undefined
console.log(Point.displayName); // "Point"
console.log(Point.distance(p1, p2)); // 7.0710678118654755
字段声明
使用类字段声明语法,构造函数小节的示例可以写成如下形式:
jsclass Rectangle {
height = 0;
width;
constructor(height, width) {
this.height = height;
this.width = width;
}
}
类字段与对象属性相似,不属于变量,所以我们不需要使用诸如 const 一类的关键字去声明它们。在 JavaScript 中,私有元素使用了一种特殊的语法,所以不应当使用像 public 和 private 这样的修饰符关键字。
如上文所示,声明字段时有没有默认值都可以。没有默认值的字段其值默认为 undefined。通过预先声明字段,类声明会变得自我文档化,并且字段始终显现,有助于优化代码。
参见公有类字段获取更多信息。
私有元素
使用私有字段,上文的声明可以细化为如下形式:
jsclass Rectangle {
#height = 0;
#width;
constructor(height, width) {
this.#height = height;
this.#width = width;
}
}
从类的外部引用私有字段是错误的,它们只能在类主体的内部被读写。通过定义在类外部不可见的内容,你可以确保类的使用者不能依赖类的内部构造,因为内部构造随着版本更新可能会发生变化。
私有字段只能在字段声明中预先声明。它们不像普通属性那样可以通过赋值创建。
私有方法和访问器也可以使用与公有方法和访问器相同的语法来定义,但标识符以 # 开头。
更多信息,参见私有元素。