Handlers for Functions

When the target is a function, apply(target, thisArg, args) runs on every call (including call(), apply() and callbacks) and construct(target, args, newTarget) runs on new and must return an object. Forwarding through Reflect.apply() and Reflect.construct() preserves this and new.target, so you can log, time, memoize or coerce arguments without touching the original code.

Logging calls and coercing constructor argumentsJavaScriptLive
const sum = (...nums) => nums.reduce((a, b) => a + b, 0);
const logged = new Proxy(sum, {
  apply(target, thisArg, args) {
    console.log(`call ${target.name}(${args})`);
    return Reflect.apply(target, thisArg, args);
  },
});
class Point { constructor(x, y) { Object.assign(this, { x, y }); } }
const NumericPoint = new Proxy(Point, {
  construct: (target, args, newTarget) => Reflect.construct(target, args.map(Number), newTarget),
});
console.log(logged(1, 2, 3), new NumericPoint("3", "4"));