Categories

← Programming Idioms
STRVCT

Extending existing classes by adding methods from separate files without subclassing.

Overview

Categories allow developers to add methods to an existing class without modifying its original file. Borrowed from Objective-C and Smalltalk traditions, categories are used throughout STRVCT to separate concerns—keeping core class files focused on essential logic while adding specialized behaviors in dedicated extension files.

A category is a class that extends the target class but executes .initThisCategory() instead of .initThisClass(). The framework copies the category's prototype and static methods onto the target class's prototype rather than creating a new class entry in the registry.

Category Extension File class SvJsonGroup_patches Extends base class .initThisCategory() Executes method merge Method Merge Engine Prototype Methods Copied to base prototype Static Methods Copied to base constructor Target Base Class SvJsonGroup Prototype Gains applyJsonPatches() instanceof Unchanged No extra prototype layer

Defining a Category (`.initThisCategory()`)

// SvJsonGroup_patches.js — adds JSON Patch methods to SvJsonGroup
(class SvJsonGroup_patches extends SvJsonGroup {

    applyJsonPatches (patches) {
        // Implementation
    }

    applyPatch (operation) {
        // Single patch operation
    }

}.initThisCategory());

Executing .initThisCategory() instructs the class registration system to merge all prototype and static methods into the parent class (SvJsonGroup). No new class entry is created in the global class registry.

Naming Conventions & `_imports.json` Order

  • File & Class Naming: Category files and classes use an underscore to separate the target base class name from the category purpose: SvJsonGroup_patches.js, Array_promises.js, Promise_ideal.js.
  • Import Dependency Order: The base class must be listed before its category files in _imports.json:
[
    "SvJsonGroup.js",
    "SvJsonGroup_patches.js",
    "SvJsonGroup_clientState.js"
]

Extending JavaScript Builtins

Categories are used heavily during boot to extend native JavaScript objects without polluting the global scope with global functions:

// Promise_ideal.js — adds clone(), status tracking, and 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());

Category Constraints & Rules

  1. No New Slots: Categories can only add methods—they cannot add new slots via initPrototypeSlots(), as prototype slots must be defined during initial class registration.
  2. instanceof Compatibility: instanceof checks are completely unaffected. An instance of SvJsonGroup answers true for instanceof SvJsonGroup and does not add a prototype link layer.
  3. Full this Access: Category methods execute with full access to this and all slots and methods of the base class.
  • Protocols: Interface declaration and conformance checking.
  • Style Guide: Coding standards and class patterns.