JS `Class` 语法高级:静态属性、静态方法与私有字段 (`#`)

咳咳,各位观众老爷,晚上好!今天咱们来聊聊 JavaScript Class 语法里那些个稍微深水区的东西:静态属性、静态方法,还有那个神秘兮兮的私有字段 #。保证让各位听完之后,感觉自己瞬间升职加薪,迎娶白富美,走向人生巅峰!(能不能实现就看你们自己了,嘿嘿)

一、 静态属性:类级别的“公有财产”

好,先说说静态属性。啥叫静态属性呢?你可以把它想象成是属于整个 Class 的“公有财产”,而不是属于某个 Class 创建出来的具体实例的。 换句话说,它不属于某个特定的对象,而是属于 Class 本身。

1. 语法糖:static 关键字

在 Class 语法里,我们用 static 关键字来定义静态属性。

class MyClass {
  static myStaticProperty = "Hello from the static property!";

  constructor(instanceProperty) {
    this.instanceProperty = instanceProperty;
  }

  static myStaticMethod() {
    console.log("This is a static method!");
  }
}

console.log(MyClass.myStaticProperty); // 输出: Hello from the static property!
// console.log(new MyClass("").myStaticProperty); // 报错,实例不能访问静态属性
MyClass.myStaticMethod(); // 输出: This is a static method!

看,myStaticProperty 就是一个静态属性。要访问它,我们直接用 MyClass.myStaticProperty,而不是通过 new MyClass().myStaticProperty。 静态方法 myStaticMethod 同理。

2. 应用场景:常量、配置、工具函数

静态属性通常用来存储一些常量、配置信息,或者一些与 Class 相关的全局数据。 举个例子:

class MathHelper {
  static PI = 3.14159;

  static calculateCircleArea(radius) {
    return MathHelper.PI * radius * radius;
  }
}

console.log(MathHelper.PI); // 输出: 3.14159
console.log(MathHelper.calculateCircleArea(5)); // 输出: 78.53975

在这个例子里,PI 就是一个静态属性,用来存储圆周率。 calculateCircleArea 是一个静态方法,它直接使用 MathHelper.PI 来进行计算,而不需要依赖任何实例。

3. 静态属性的特点小结:

特点 说明
——————

二、 静态方法:与Class相关的工具函数

静态方法,顾名思义,就是用 static 关键字定义的方法。它和静态属性一样,也是属于Class本身的,而不是属于某个实例的。

class MyClass {
    static staticMethod() {
        console.log("Hello, I'm a static method!");
    }
}

MyClass.staticMethod(); // 直接通过类名调用静态方法

1. 静态方法与实例方法区别

  • 调用方式: 静态方法通过类名调用,实例方法通过实例对象调用。
  • this 指向: 静态方法中的 this 指向的是 Class 本身,而不是某个实例。 实例方法中的 this 指向的是调用该方法的实例对象。
  • 访问权限: 静态方法只能访问静态属性和静态方法,不能直接访问实例属性和实例方法。 实例方法可以访问实例属性、实例方法,以及静态属性和静态方法。
class Example {
  static count = 0;

  constructor() {
    Example.count++; // 每次创建实例,静态属性 count 加 1
  }

  static getCount() {
    return Example.count;
  }

  instanceMethod() {
    console.log("Instance method, current count:", Example.getCount());
  }
}

const obj1 = new Example();
const obj2 = new Example();

console.log("Total count:", Example.getCount()); // 输出:Total count: 2
obj1.instanceMethod(); // 输出:Instance method, current count: 2

2. 应用场景:辅助函数、工厂方法

静态方法通常用来定义一些辅助函数,或者一些与 Class 相关的工具函数。 另外一个常见的应用场景是作为工厂方法,用来创建 Class 的实例。

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  static createZeroPoint() {
    return new Point(0, 0);
  }

  static createRandomPoint() {
    const x = Math.random() * 100;
    const y = Math.random() * 100;
    return new Point(x, y);
  }
}

const origin = Point.createZeroPoint(); // 创建原点
const randomPoint = Point.createRandomPoint(); // 创建随机点

console.log(origin); // 输出:Point { x: 0, y: 0 }
console.log(randomPoint); // 输出:Point { x: 42.123..., y: 78.901... }

在这个例子里,createZeroPointcreateRandomPoint 都是静态方法,它们用来创建 Point 类的实例。 这种模式被称为工厂方法,它可以用来隐藏对象的创建细节,或者提供更灵活的创建方式。

三、 私有字段:# 的秘密花园

好,接下来,咱们来聊聊今天最神秘的主角:私有字段。 在 JavaScript 中,实现真正的私有性一直是个老大难问题。 以前,我们通常用命名约定(比如在属性名前面加一个下划线 _)来表示一个属性是私有的,但这只是一种“君子协定”,并不能阻止外部访问。

class MyClass {
  _privateProperty = "This is supposed to be private!";

  getPrivateProperty() {
    return this._privateProperty;
  }
}

const obj = new MyClass();
console.log(obj._privateProperty); // 仍然可以访问,只是不建议这样做

但是,现在不一样了! ES2019 引入了真正的私有字段,使用 # 前缀来声明。


class MyClass {
  #privateField = "This is truly private!";

  getPrivateField() {
    return this.#privateField;
  }
}

const obj = new MyClass();
// console.log(obj.#privateField); // 报错:Private field '#privateField' must be declared in an enclosing class
console.log(obj.getPrivateField()); // 输出

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注