Extending existing classes by adding methods from separate files.
Categories allow you to add methods to an existing class without modifying its original file. This is borrowed from Objective-C/Smalltalk traditions and is used throughout STRVCT to separate concerns — keeping core class files focused on essential functionality while adding specialized behavior in dedicated files.
A category is a class that extends the target class but calls initThisCategory() instead of initThisClass(). The framework copies the category's methods onto the target class's prototype rather than creating a new class in the hierarchy.
// SvJsonGroup_patches.js — adds JSON Patch support to SvJsonGroup
(class SvJsonGroup_patches extends SvJsonGroup {
applyJsonPatches (patches) {
// patch implementation
}
applyPatch (operation) {
// single patch operation
}
}.initThisCategory());The key difference from a normal class: .initThisCategory() instead of .initThisClass(). This tells the framework to merge the methods into the parent class rather than registering a new class.
Category files use an underscore to separate the base class name from the category purpose:
SvJsonGroup.js // base class
SvJsonGroup_patches.js // JSON Patch operations
SvJsonGroup_clientState.js // client state tool methodsThe category class name follows the same pattern: SvJsonGroup_patches, Array_promises, Promise_ideal.
Base classes must be loaded before their categories. In _imports.json files, list the base class first:
[
"SvJsonGroup.js",
"SvJsonGroup_patches.js",
"SvJsonGroup_clientState.js"
]If a category loads before its base class, the extends clause will fail because the base class doesn't exist yet.
Categories are commonly used to extend native JavaScript classes. The boot system includes several:
// Promise_ideal.js — adds clone(), status tracking, timeouts
(class Promise_ideal extends Promise {
static clone () { /* ... */ }
callResolveFunc (...args) { /* ... */ }
isPending () { /* ... */ }
}.initThisCategory());
// Array_promises.js — adds async iteration methods
(class Array_promises extends Array {
async promiseSerialForEach (aBlock) { /* ... */ }
async promiseParallelMap (aBlock) { /* ... */ }
}.initThisCategory());After these categories load, every Promise and Array instance has the new methods — no imports needed.
Good uses:
Avoid when:
initThisCategory() iterates over the category class's own methods (both prototype and static) and copies them onto the target class. It does not create a new entry in the class registry — SvJsonGroup_patches is not a class you can instantiate or look up by name. It's purely a delivery mechanism for methods.
This means:
instanceof checks are unaffected — an SvJsonGroup instance won't show as instanceof SvJsonGroup_patchesthis and the base class's slots and methodsinitPrototypeSlots / initPrototype and the initialization chain, which categories cannot participate in (only methods are merged)