静态方法和属性
静态方法与属性的基本概念
ECMAScript 6引入了类的静态方法和属性,它们直接属于类本身而非类的实例。静态成员通过static
关键字定义,只能通过类名访问,不能通过实例调用。这种特性特别适合工具函数或类级别的常量。
class MathUtils {
static PI = 3.1415926;
static sum(...numbers) {
return numbers.reduce((a, b) => a + b, 0);
}
}
console.log(MathUtils.PI); // 3.1415926
console.log(MathUtils.sum(1, 2, 3)); // 6
const utils = new MathUtils();
console.log(utils.PI); // undefined
utils.sum(1, 2); // TypeError
静态方法的特性
静态方法中的this
指向类本身而非实例,这使得它们可以:
- 访问其他静态成员
- 作为工厂方法创建实例
- 实现工具函数集合
class User {
static roles = ['admin', 'editor', 'guest'];
constructor(name) {
this.name = name;
}
static createAdmin(name) {
const user = new User(name);
user.role = this.roles[0]; // 访问静态属性
return user;
}
static validateEmail(email) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}
}
const admin = User.createAdmin('Alice');
console.log(User.validateEmail('test@example.com')); // true
静态属性的高级用法
静态属性可以存储类级别的状态信息,配合私有静态字段(ES2022)可以实现更安全的封装:
class Counter {
static #count = 0; // 私有静态字段
static increment() {
this.#count++;
}
static get value() {
return this.#count;
}
}
Counter.increment();
console.log(Counter.value); // 1
console.log(Counter.#count); // SyntaxError
继承中的静态成员
静态成员也会被继承,子类可以通过super
访问父类的静态方法:
class Animal {
static planet = 'Earth';
static getPlanet() {
return this.planet;
}
}
class Dog extends Animal {
static planet = 'Mars';
static displayPlanet() {
console.log(super.getPlanet()); // 通过super调用父类静态方法
}
}
console.log(Dog.getPlanet()); // "Mars"
Dog.displayPlanet(); // "Earth"
实际应用场景
- 配置管理:集中存储类相关配置
class ApiClient {
static baseURL = 'https://api.example.com';
static timeout = 5000;
static configure({ url, timeout }) {
this.baseURL = url;
this.timeout = timeout;
}
}
- 缓存实现:共享缓存数据
class DataCache {
static #cache = new Map();
static set(key, value) {
this.#cache.set(key, value);
}
static get(key) {
return this.#cache.get(key);
}
}
- 单例模式:确保类只有一个实例
class AppConfig {
static #instance;
constructor() {
if (AppConfig.#instance) {
return AppConfig.#instance;
}
this.settings = {};
AppConfig.#instance = this;
}
static getInstance() {
if (!this.#instance) {
this.#instance = new AppConfig();
}
return this.#instance;
}
}
与实例方法的对比
特性 | 静态方法 | 实例方法 |
---|---|---|
调用方式 | ClassName.method() |
instance.method() |
this 指向 |
类本身 | 实例对象 |
内存分配 | 类加载时创建一次 | 每个实例都会创建 |
适用场景 | 工具函数/类级别操作 | 实例相关操作 |
class Logger {
static logLevel = 'INFO';
// 静态方法处理类级别逻辑
static setGlobalLevel(level) {
this.logLevel = level;
}
// 实例方法处理实例特定逻辑
log(message) {
console.log(`[${this.constructor.logLevel}] ${message}`);
}
}
静态初始化块
ES2022引入的静态初始化块,用于复杂的静态属性初始化:
class Database {
static connection;
static #privateKey;
static {
// 执行异步初始化
this.#privateKey = generateKey();
initializeDB().then(conn => {
this.connection = conn;
});
}
static async query(sql) {
await this.connection.ready();
return this.connection.execute(sql);
}
}
常见问题与解决方案
- 箭头函数中的
this
:
class Timer {
static delay = 1000;
static setDelay = () => { // 箭头函数绑定类作为this
console.log(this.delay);
};
}
const fn = Timer.setDelay;
fn(); // 正常输出1000
- 混入静态方法:
const Loggable = Base => class extends Base {
static log(msg) {
console.log(`[LOG] ${msg}`);
}
};
class Service extends Loggable(Object) {}
Service.log('System started');
- 动态访问静态成员:
class DynamicAccess {
static value = 42;
static getValue(prop) {
return this[prop]; // 等同于DynamicAccess[prop]
}
}
console.log(DynamicAccess.getValue('value')); // 42
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:constructor方法
下一篇:类的继承extends