Metaprogrammierung und Reflexion

Geschätzte Lektüre: 4 Minuten 348 Ansichten

Metaprogrammierung ermöglicht es Programmen, andere Programme zu manipulieren oder sich selbst zu modifizieren. JavaScript bietet verschiedene Mechanismen für metaprogrammative Techniken:

// Proxies für transparente Objektmanipulation
const observableObject = (target, observer) => {
    return new Proxy(target, {
        set(obj, prop, value) {
            const oldValue = obj[prop];
            obj[prop] = value;
            observer.notify(prop, oldValue, value);
            return true;
        },
        
        get(obj, prop) {
            if (typeof obj[prop] === 'function') {
                return obj[prop].bind(obj);
            }
            observer.access(prop, obj[prop]);
            return obj[prop];
        }
    });
};

class PropertyObserver {
    notify(property, oldValue, newValue) {
        console.log(`${property}: ${oldValue}${newValue}`);
    }
    
    access(property, value) {
        console.log(`Zugriff auf ${property}: ${value}`);
    }
}

const user = observableObject({name: "Max", age: 30}, new PropertyObserver());
user.name = "Maria"; // Ausgabe: name: Max → Maria

// Reflection API
const ReflectiveClass = class {
    constructor(data) {
        Object.assign(this, data);
    }
    
    static fromJSON(json) {
        return Reflect.construct(this, [JSON.parse(json)]);
    }
    
    getMethodNames() {
        return Reflect.ownKeys(Object.getPrototypeOf(this))
            .filter(key => typeof this[key] === 'function' && key !== 'constructor');
    }
    
    callMethod(methodName, ...args) {
        if (Reflect.has(this, methodName)) {
            return Reflect.apply(this[methodName], this, args);
        }
        throw new Error(`Methode ${methodName} existiert nicht`);
    }
};

// Decorator Pattern mit Funktionen
const measureTime = (target, propertyKey, descriptor) => {
    const originalMethod = descriptor.value;
    
    descriptor.value = function(...args) {
        const start = performance.now();
        const result = originalMethod.apply(this, args);
        const end = performance.now();
        console.log(`${propertyKey} dauerte ${end - start} Millisekunden`);
        return result;
    };
    
    return descriptor;
};

// Symbol-basierte Metadaten
const METADATA = Symbol('metadata');

class MetadataClass {
    constructor() {
        this[METADATA] = {
            created: new Date(),
            version: '1.0.0'
        };
    }
    
    getMetadata() {
        return this[METADATA];
    }
    
    setMetadata(key, value) {
        this[METADATA][key] = value;
    }
}
Dieses Dokument teilen

Metaprogrammierung und Reflexion

Oder Link kopieren

INHALT

Abonnieren

×
Cancel