摘要:在本教程中,您将了解 JavaScript 私有字段以及如何有效地使用它们。
JavaScript 私有字段简介
ES2022 允许您为 类 定义私有字段。要定义私有字段,您需要在字段名前添加 #
符号。
例如,以下代码定义了 Circle
类,它包含一个私有字段 radius
class Circle {
#radius;
constructor(value) {
this.#radius = value;
}
get area() {
return Math.PI * Math.pow(this.#radius, 2);
}
}
Code language: JavaScript (javascript)
在这个例子中
- 首先,在类主体中定义私有字段
#radius
。 - 其次,在构造函数中使用参数初始化
#radius
字段。 - 第三,通过在 getter 方法中访问
#radius
私有字段来计算圆的面积。
以下代码创建了 Circle
类的新的实例并计算了它的面积
let circle = new Circle(10);
console.log(circle.area); // 314.1592653589793
Code language: JavaScript (javascript)
由于 #radius
是一个私有字段,您只能在 Circle
类内部访问它。换句话说,#radius
字段在 Circle
类之外是不可见的。
使用 getter 和 setter 访问私有字段
以下代码通过添加 radius
getter 和 setter 来重新定义 Circle
类,以便访问 #radius
私有字段
class Circle {
#radius = 0;
constructor(radius) {
this.radius = radius; // calling setter
}
get area() {
return Math.PI * Math.pow(this.#radius, 2);
}
set radius(value) {
if (typeof value === 'number' && value > 0) {
this.#radius = value;
} else {
throw 'The radius must be a positive number';
}
}
get radius() {
return this.#radius;
}
}
Code language: JavaScript (javascript)
工作原理。
radius
setter 在将参数分配给#radius
私有字段之前验证参数。如果参数不是正数,radius
setter 将抛出错误。radius
getter 返回#radius
私有字段的值。- 构造函数调用
radius
setter 将参数分配给#radius
私有字段。
私有字段和子类
私有字段只能在定义它们的类内部访问。此外,它们也无法从子类访问。例如,以下代码定义了 Cylinder
类,该类 扩展 了 Circle
类
class Cylinder extends Circle {
#height;
constructor(radius, height) {
super(radius);
this.#height = height;
// cannot access the #radius of the Circle class here
}
}
Code language: JavaScript (javascript)
如果您试图在 Cylinder
类中访问 #radius
私有字段,您将得到一个 SyntaxError
错误。
in
运算符:检查私有字段是否存在
要检查对象是否在类内部包含私有字段,您可以使用 in
运算符
fieldName in objectName
例如,以下代码在 Circle
类中添加了 hasRadius()
静态方法,该方法使用 in
运算符检查 circle
对象是否包含 #radius
私有字段
class Circle {
#radius = 0;
constructor(radius) {
this.radius = radius;
}
get area() {
return Math.PI * Math.pow(this.radius, 2);
}
set radius(value) {
if (typeof value === 'number' && value > 0) {
this.#radius = value;
} else {
throw 'The radius must be a positive number';
}
}
get radius() {
return this.#radius;
}
static hasRadius(circle) {
return #radius in circle;
}
}
let circle = new Circle(10);
console.log(Circle.hasRadius(circle));
Code language: JavaScript (javascript)
输出
true
Code language: JavaScript (javascript)
静态私有字段
以下示例展示了如何使用静态私有字段
class Circle {
#radius = 0;
static #count = 0;
constructor(radius) {
this.radius = radius; // calling setter
Circle.#count++;
}
get area() {
return Math.PI * Math.pow(this.radius, 2);
}
set radius(value) {
if (typeof value === 'number' && value > 0) {
this.#radius = value;
} else {
throw 'The radius must be a positive number';
}
}
get radius() {
return this.#radius;
}
static hasRadius(circle) {
return #radius in circle;
}
static getCount() {
return Circle.#count;
}
}
let circles = [new Circle(10), new Circle(20), new Circle(30)];
console.log(Circle.getCount());
Code language: JavaScript (javascript)
工作原理。
首先,在 Circle
类中添加一个私有静态字段 #count
,并将它的值初始化为零
static #count = 0;
Code language: JavaScript (javascript)
其次,在构造函数中将 #count
增加一
Circle.#count++;
Code language: JavaScript (javascript)
第三,定义一个静态方法,该方法返回 #count
私有静态字段的值
static getCount() {
return Circle.#count;
}
Code language: JavaScript (javascript)
最后,创建 Circle
类的三个实例并将 count
值输出到控制台
let circles = [new Circle(10), new Circle(20), new Circle(30)];
console.log(Circle.getCount());
Code language: JavaScript (javascript)
总结
- 在字段名前添加
#
符号,将其设置为私有字段。 - 私有字段只能在类内部访问,不能在类外部或子类中访问。
- 使用
in
运算符检查对象是否包含私有字段。
本教程对您有帮助吗?