Static Initialization of Classes
Introducing the static initialization method used in the code that creates and manages categories on my blog, and a case of improvement to better code.
In my blog project, I designed Category.js using class syntax to manage categories.
The most important aspect during design was minimizing member exposure.
I declared all members as private with #
to prevent direct external access,
and when member exposure was necessary, I provided only getters for fields to restrict writing, and converted methods to public methods.
Initial Design
I wanted Category.js
to have a structure that returns category instances through static methods without instantiation through the new
keyword.
import Category from '$lib/post/Category.js';
Category.getCategory("Windows") // Returns Windows category instance
Design to get already created category instances through static methods
To use it this way, initialization had to occur internally simultaneously with import without separate initialization. After considering how to initialize simultaneously with import without exposing methods externally,
- I declared a "Symbol" outside the class,
- Used the "Symbol" as a method name inside the class,
- And implemented an initialization method that isn't exposed externally by executing that method.
const symbol = Symbol('Category initialization');
export default class Category {
static [symbol]() {
// ...init
}
}
Category[symbol]();
Initialization method preventing external access by defining method names using symbols
However, this approach had drawbacks. Using reflection, the initialization method could be accessed, and there was a possibility of re-executing initialization through this. Improvements were needed to prevent this issue in the future.
Improvement with Static Initialization Block
In Java, you can initialize static and instance members through {}
blocks.
JavaScript can also apply this to class syntax to make the code more concise.
Prototypes can implement static initialization logic using Immediately Invoked Function Expressions, "IIFE".
const symbol = Symbol('Category initialization'); // [!code --]
export default class Category {
static [symbol]() { // [!code --]
static { // [!code ++]
this.#member = data; // Can use 'this' keyword in static initialization // [!code ++]
// ...init
}
}
Category[symbol](); // [!code --]
Initialization inside the class through static initialization block
Differences in Initialization Blocks Between Java and JavaScript
In Java, you can use two types of initialization blocks:
static {}
, static initialization block{}
, instance initialization block
In contrast, JavaScript can only use one type of initialization block:
static {}
, static initialization block
Additionally, Java and JavaScript differ in the use of the this
keyword in initialization blocks.
Java can only use this
after instance creation,
but JavaScript, being a first-class object, can use this
in static initialization blocks to access static members.
This difference is because JavaScript better supports functional programming characteristics.