A cross-cutting concern is behavior that affects multiple parts of a program rather than belonging naturally to one module or class. Examples include logging, tracing, and performance tracking. section 7.0 section 7.6
JavaScript’s Proxy and Reflect APIs can weave behavior into object use at runtime, keeping injected code separate from the application object. Method decorators use this approach to run actions before and after selected methods. section 7.6 section 7.7
Listing 7.37 Main logic that applies a decorator to a proxy object
const decorate = (decorator, obj) => new Proxy(obj, {
get(target, key) {
if (!decorator.methods.includes(key)) {
return Reflect.get(...arguments);
}
const methodRef = target[key]; #1
return (...capturedArgs) => { #2
const newArgs = #3
decorator.actions?.before.call(target, ...capturedArgs);
const result = methodRef.call(target, ...[newArgs]); #4
return decorator.actions?.after.call(target, result) ; #5
};
}
})
This decorator wrapper intercepts selected method access, preprocesses arguments, calls the original method, and postprocesses its result. section 7.7
Validating Counter methods
A validation decorator checks arguments to Counter.inc and Counter.dec before the methods run. A negative value aborts the operation with a RangeError; an identity action leaves the result unchanged. section 7.7

