The improved class function
Class Field Declarations
ECMAScript 15 introduced significant improvements to class field declarations. Fields can now be declared directly in the class body without needing initialization in the constructor. This syntactic sugar makes class definitions more concise and clear.
class Person {
name = 'Anonymous';
age = 0;
constructor(name, age) {
this.name = name;
this.age = age;
}
}
Field declarations support default values and can also be reassigned in the constructor. This enhancement reduces boilerplate code, allowing class definitions to focus more on business logic.
Private Class Fields
ECMAScript 15 introduced true private field syntax by prefixing field names with #
. These fields can only be accessed within the class and are not directly accessible from outside.
class Counter {
#count = 0; // Private field
increment() {
this.#count++;
}
getCount() {
return this.#count;
}
}
const counter = new Counter();
counter.increment();
console.log(counter.getCount()); // 1
console.log(counter.#count); // Error: Private field cannot be accessed outside the class
Private fields address the long-standing issue of JavaScript lacking true private members, providing better encapsulation.
Static Class Fields and Methods
Static fields and methods can now be declared directly in the class body using the static
keyword. These members belong to the class itself rather than instances.
class MathUtils {
static PI = 3.14159;
static circleArea(radius) {
return this.PI * radius * radius;
}
}
console.log(MathUtils.PI); // 3.14159
console.log(MathUtils.circleArea(5)); // 78.53975
Static fields are ideal for storing class-level constants or utility methods, reducing pollution of the global namespace.
Private Static Fields and Methods
Combining the features of private fields and static members, ECMAScript 15 supports private static fields and methods.
class Logger {
static #logLevel = 'INFO';
static #validateLevel(level) {
return ['DEBUG', 'INFO', 'WARN', 'ERROR'].includes(level);
}
static setLogLevel(level) {
if (this.#validateLevel(level)) {
this.#logLevel = level;
}
}
static getLogLevel() {
return this.#logLevel;
}
}
Logger.setLogLevel('DEBUG');
console.log(Logger.getLogLevel()); // DEBUG
This combination provides class-level private state and logic encapsulation, enhancing modular design capabilities.
Class Static Initialization Blocks
ECMAScript 15 introduced static initialization blocks for executing complex static initialization logic when a class is defined.
class Database {
static connection;
static #initialized = false;
static {
// Simulate asynchronous initialization
setTimeout(() => {
this.connection = 'Connected to database';
this.#initialized = true;
console.log('Database initialized');
}, 1000);
}
static query(sql) {
if (!this.#initialized) {
throw new Error('Database not initialized');
}
return `Executing: ${sql}`;
}
}
// Use later
setTimeout(() => {
console.log(Database.query('SELECT * FROM users'));
}, 1500);
Static initialization blocks are particularly suitable for scenarios requiring asynchronous initialization or complex configuration, offering a more flexible way to initialize classes.
New Features in Class Methods
Class methods now support more features, including generator methods, async methods, and improvements to accessor properties.
class Collection {
#items = [];
*[Symbol.iterator]() {
yield* this.#items;
}
async fetchAll() {
// Simulate async data fetching
return new Promise(resolve => {
setTimeout(() => resolve(this.#items), 500);
});
}
get size() {
return this.#items.length;
}
set size(newSize) {
if (newSize < 0) throw new RangeError('Size cannot be negative');
this.#items.length = newSize;
}
}
const coll = new Collection();
coll.size = 5;
console.log(coll.size); // 5
These enhancements allow class methods to better support various modern JavaScript programming patterns.
Enhancements to Class Inheritance
ECMAScript 15 introduced several enhancements to class inheritance, including better super
call support and new inheritance patterns.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
#breed;
constructor(name, breed) {
super(name);
this.#breed = breed;
}
speak() {
super.speak();
console.log(`${this.name} barks. It's a ${this.#breed}.`);
}
static createDefault() {
return new this('Buddy', 'Golden Retriever');
}
}
const dog = Dog.createDefault();
dog.speak();
The inheritance system is now more robust, supporting patterns like new this
in static methods, offering greater flexibility.
New Forms of Class Expressions
ECMAScript 15 expanded the syntax of class expressions, supporting more forms of class definitions.
// Named class expression
const Person = class NamedPerson {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
};
// Class expression passed as a parameter
function createClass(baseClass = class {}) {
return class extends baseClass {
created = new Date();
};
}
const Timestamped = createClass();
const obj = new Timestamped();
console.log(obj.created); // Current date and time
These enhancements to class expressions allow classes to be used as first-class citizens in JavaScript, supporting more advanced metaprogramming patterns.
Class Decorator Proposal
Although not yet an official standard, ECMAScript 15 laid the groundwork for the class decorator proposal. Decorators provide a declarative way to modify class behavior.
// Assuming the decorator proposal is implemented
function logged(constructor) {
return class extends constructor {
constructor(...args) {
super(...args);
console.log(`Instance created with args: ${args}`);
}
};
}
@logged
class Calculator {
add(a, b) {
return a + b;
}
}
const calc = new Calculator(); // Logs output
console.log(calc.add(2, 3)); // 5
The decorator pattern provides powerful metaprogramming capabilities for classes. While still in the proposal stage, ECMAScript 15 has prepared the way for it.
Better Integration of Classes and Modules
ECMAScript 15 improved the integration of classes with the module system, making class imports and exports more flexible.
// module.js
export class PublicClass {
#privateField = 'secret';
publicMethod() {
return this.#privateField;
}
}
// Default class export
export default class DefaultClass {
static version = '1.0';
}
// main.js
import DefaultClass, { PublicClass } from './module.js';
const instance = new PublicClass();
console.log(instance.publicMethod()); // secret
This enhancement allows classes to better serve as components of the module system, supporting clearer code organization.
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn