3

JavaScript 私有字段

 1 year ago
source link: https://www.myfreax.com/javascript-private-fields/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
JavaScript 私有字段

JavaScript 私有字段

在本教程中,您将了解 JavaScript 私有字段以及如何有效地使用它们。

JavaScript 私有字段介绍

ES2022 允许您为定义私有字段。要定义私有字段,请在字段名称前加上符号 #

例如,以下定义 Circle 类具有私有字段 radius

class Circle {
  #radius;
  constructor(value) {
    this.#radius = value;
  }
  get area() {
    return Math.PI * Math.pow(this.#radius, 2);
  }
}

在这个例子中:

  • 首先,在类主体中定义私有字段  #radius
  • 其次,在构造函数初始化的字段 #radius
  • 第三,通过 area 的 getter 方法访问私有字段 #radius 来计算圆的面积。

下面创建一个Circle类的实例并计算它的面积:

let circle = new Circle(10);
console.log(circle.area); // 314.1592653589793

因为 #radius 是私有字段,所以只能在 Circle 类内部访问。换句话说,#radius字段在 Circle 类之外是不可见的。

使用 getter 和 setter 访问私有字段

下面重新定义 Circle 类并添加radiusgetter 和 setter 来以提供对#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;
  }
}

怎么运行的。

  • radius setter 在将参数分配给私有字段 #radius 之前验证参数。如果参数不是正数,radius setter 会抛出错误。
  • radius getter 返回私有字段 #radius 的值。
  • 构造函数调用radius setter 将参数分配给 #radius 私有字段。

私有字段和子类

私有字段只能在定义它们的类访问。此外,它们不能从子类访问。例如,下面定义Cylinder 类,Circle 扩展Cylinder

class Cylinder extends Circle {
  #height;
  constructor(radius, height) {
    super(radius);
    this.#height = height;

    // 不能访问 #radius 在 Circle 类
  }
}

如果您尝试访问 Cylinder 类的私有字段 #radius ,您将获得一个 SyntaxError.

运算符 in 检查私有字段是否存在

要检查一个对象是否存在私有字段在类,您可以使用 in 运算符:

fieldName in objectName

例如,下面将静态方法 hasRadius() 添加到 Circle 类,它使用 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));
true

静态私有字段

以下示例展示如何使用静态私有字段:

class Circle {
  #radius = 0;
  static #count = 0;
  constructor(radius) {
    this.radius = radius;
    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());

怎么运行的。

首先,添加一个私有静态字段 #countCircle 类并将其值初始化为零:

static #count = 0;

其次,在构造函数使 #count 增加 1:

Circle.#count++;

第三,定义一个返回私有静态字段 #count 值的静态方法:

static getCount() {
    return Circle.#count;
}

最后,创建 Circle 类的三个实例并将 count 值输出到控制台:

let circles = [new Circle(10), new Circle(20), new Circle(30)];
console.log(Circle.getCount());
  • 在字段名称前加上 #符 号标记字段为私有。
  • 私有字段只能在类内部访问,不能从类或子类外部访问。
  • 使用 in 运算符检查对象是否存在指定的私有字段。

微信公众号

支付宝打赏

myfreax 淘宝打赏

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK